Commit c183b2f9 authored by Alex Margarit's avatar Alex Margarit

Merge branch 'dev_platform'

parents 8898ae50 da6c52d5
......@@ -24,7 +24,7 @@ import re
from utils.tool import Tool
g_tool = Tool('UmbrellaHeader ...')
g_re_include = re.compile('^#include "(\w+/a_[\w_\.]+\.h)"$')
g_re_include = re.compile('^#include "((\w+/)+a_[\w_\.]+\.h)"$')
g_included_files = {}
def main():
......
......@@ -76,21 +76,21 @@ def main():
license_header = """\
/*
Copyright {date} {author}
This file is part of a2x, a C video game framework.
Copyright {date} {author}
This file is part of a2x, a C video game framework.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/""".format(date = time.strftime('%Y'), author = author)
g_tool.write_text(pack_c,
......
......@@ -17,6 +17,10 @@ geany -i \
src/math/* \
src/memory/* \
src/platform/* \
src/platform/graphics/* \
src/platform/input/* \
src/platform/sound/* \
src/platform/system/* \
src/sound/* \
src/strings/* \
src/time/* \
......
......@@ -77,7 +77,7 @@ A_GENERIC_CFLAGS := \
$(A_CONFIG_BUILD_CFLAGS) \
$(A_CONFIG_BUILD_OPT) \
.PHONY : all clean cleanbin run
.PHONY : all run clean cleanbin $(A_CONFIG_MAKE_CLEAN)
.SECONDARY : $(A_FILES_GFX_C)
......@@ -122,8 +122,8 @@ $(A_DIR_GEN)/%.c.o : $(A_DIR_GEN)/%.c
@ mkdir -p $(@D)
$(CC) -c -o $@ $< $(A_GENERIC_CFLAGS)
clean : $(A_CONFIG_MAKE_CLEAN)
rm -rf $(A_FILE_TARGET_BIN) $(A_DIR_OBJ)
clean : cleanbin $(A_CONFIG_MAKE_CLEAN)
rm -rf $(A_DIR_OBJ)
cleanbin :
rm -f $(A_FILE_TARGET_BIN)
......
......@@ -25,7 +25,6 @@ typedef struct APixels APixels;
#include "general/a_main.v.h"
#include "graphics/a_color.v.h"
#include "math/a_fix.v.h"
#include "platform/a_platform.v.h"
typedef enum {
A_PIXELS__ALLOC = A_FLAG_BIT(0),
......
......@@ -21,6 +21,7 @@
#include "graphics/a_sprite.p.h"
#include "graphics/a_pixels.v.h"
#include "platform/a_platform.v.h"
extern APixels* a_sprite__pixelsGet(ASprite* Sprite);
extern APlatformTexture* a_sprite__textureGet(const ASprite* Sprite, unsigned Frame);
......
......@@ -31,9 +31,9 @@ typedef void APlatformSoundSample;
typedef struct APlatformTexture APlatformTexture;
#include "general/a_main.v.h"
#include "graphics/a_sprite.v.h"
#include "inputs/a_analog.v.h"
#include "inputs/a_button.v.h"
#include "math/a_fix.v.h"
extern const APack a_pack__platform;
......
/*
Copyright 2017 Alex Margarit <alex@alxm.org>
This file is part of a2x, a C video game framework.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "platform/a_sdl_render.p.h"
/*
Copyright 2016-2019 Alex Margarit <alex@alxm.org>
This file is part of a2x, a C video game framework.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <a2x.v.h>
#if A_CONFIG_LIB_RENDER_SDL
#include <SDL2/SDL.h>
typedef enum {
A_TEXTURE__INVALID = -1,
A_TEXTURE__NORMAL, // non-colorkey: alpha:0xff
A_TEXTURE__COLORMOD_BITMAP, // colorkey: RGB:0xffffff
A_TEXTURE__COLORMOD_FLAT, // non-colorkey: RGB:0xffffff
A_TEXTURE__NUM
} APlatformTextureVersion;
struct APlatformTexture {
SDL_Texture* texture[A_TEXTURE__NUM];
};
extern SDL_Renderer* a__sdlRenderer;
APlatformTexture* a_platform_api__textureNew(const APixels* Pixels, unsigned Frame)
{
APlatformTexture* texture = a_mem_zalloc(sizeof(APlatformTexture));
const APixel* original = a_pixels__bufferGetStart(Pixels, Frame);
APixel* buffer = a_mem_dup(original, Pixels->bufferSize);
for(int t = 0; t < A_TEXTURE__NUM; t++) {
switch(t) {
case A_TEXTURE__NORMAL: {
for(int i = Pixels->w * Pixels->h; i--; ) {
if(original[i] != a_color__key) {
// Set full alpha for non-transparent pixel
buffer[i] |= (APixel)A__PX_MASK_A << A__PX_SHIFT_A;
}
}
} break;
case A_TEXTURE__COLORMOD_BITMAP: {
for(int i = Pixels->w * Pixels->h; i--; ) {
if(original[i] == a_color__key) {
// Set full color for transparent pixel
buffer[i] |= a_pixel_fromHex(0xffffff);
}
}
} break;
case A_TEXTURE__COLORMOD_FLAT: {
for(int i = Pixels->w * Pixels->h; i--;) {
if(original[i] != a_color__key) {
// Set full color for non-transparent pixel
buffer[i] |= a_pixel_fromHex(0xffffff);
}
}
} break;
}
SDL_Texture* tex = SDL_CreateTexture(a__sdlRenderer,
A_SDL__PIXEL_FORMAT,
SDL_TEXTUREACCESS_TARGET,
Pixels->w,
Pixels->h);
if(tex == NULL) {
A__FATAL("SDL_CreateTexture: %s", SDL_GetError());
}
if(SDL_UpdateTexture(
tex, NULL, buffer, Pixels->w * (int)sizeof(APixel)) < 0) {
A__FATAL("SDL_UpdateTexture: %s", SDL_GetError());
}
if(SDL_SetTextureBlendMode(tex, SDL_BLENDMODE_BLEND) < 0) {
a_out__error("SDL_SetTextureBlendMode: %s", SDL_GetError());
}
texture->texture[t] = tex;
}
free(buffer);
return texture;
}
void a_platform_api__textureFree(APlatformTexture* Texture)
{
if(Texture == NULL) {
return;
}
for(int t = A_TEXTURE__NUM; t--; ) {
if(Texture->texture[t]) {
SDL_DestroyTexture(Texture->texture[t]);
}
}
free(Texture);
}
void a_platform_api__textureBlit(const APlatformTexture* Texture, const APixels* Pixels, unsigned Frame, int X, int Y)
{
a_platform_api__textureBlitEx(Texture,
Pixels,
Frame,
X + Pixels->w / 2,
Y + Pixels->h / 2,
A_FIX_ONE,
0,
0,
0);
}
void a_platform_api__textureBlitEx(const APlatformTexture* Texture, const APixels* Pixels, unsigned Frame, int X, int Y, AFix Scale, unsigned Angle, int CenterX, int CenterY)
{
A_UNUSED(Frame);
SDL_Texture* tex;
SDL_BlendMode blend =
(SDL_BlendMode)a_platform_sdl_video__pixelBlendToSdlBlend();
if(a__color.fillBlit) {
tex = Texture->texture[A_TEXTURE__COLORMOD_FLAT];
} else if(blend == SDL_BLENDMODE_MOD) {
tex = Texture->texture[A_TEXTURE__COLORMOD_BITMAP];
} else {
tex = Texture->texture[A_TEXTURE__NORMAL];
}
if(SDL_SetTextureBlendMode(tex, blend) < 0) {
a_out__error("SDL_SetTextureBlendMode: %s", SDL_GetError());
}
if(SDL_SetTextureAlphaMod(
tex, a_platform_sdl_video__pixelAlphaToSdlAlpha()) < 0) {
a_out__error("SDL_SetTextureAlphaMod: %s", SDL_GetError());
}
if(a__color.fillBlit) {
if(SDL_SetTextureColorMod(tex,
(uint8_t)a__color.rgb.r,
(uint8_t)a__color.rgb.g,
(uint8_t)a__color.rgb.b) < 0) {
a_out__error("SDL_SetTextureColorMod: %s", SDL_GetError());
}
}
SDL_Point center = {
a_fix_toInt((Pixels->w / 2 + CenterX) * Scale),
a_fix_toInt((Pixels->h / 2 + CenterY) * Scale)
};
SDL_Rect dest = {X - center.x,
Y - center.y,
a_fix_toInt(Pixels->w * Scale),
a_fix_toInt(Pixels->h * Scale)};
if(SDL_RenderCopyEx(a__sdlRenderer,
tex,
NULL,
&dest,
360 - 360 * Angle / A_FIX_ANGLES_NUM,
&center,
SDL_FLIP_NONE) < 0) {
a_out__error("SDL_RenderCopyEx: %s", SDL_GetError());
}
if(a__color.fillBlit) {
if(SDL_SetTextureColorMod(tex, 0xff, 0xff, 0xff) < 0) {
a_out__error("SDL_SetTextureColorMod: %s", SDL_GetError());
}
}
}
#endif // A_CONFIG_LIB_RENDER_SDL
/*
Copyright 2017 Alex Margarit <alex@alxm.org>
This file is part of a2x, a C video game framework.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "platform/graphics/a_sdl_blit.p.h"
......@@ -21,73 +21,8 @@
#if A_CONFIG_LIB_RENDER_SDL
#include <SDL2/SDL.h>
typedef enum {
A_TEXTURE__INVALID = -1,
A_TEXTURE__NORMAL, // non-colorkey: alpha:0xff
A_TEXTURE__COLORMOD_BITMAP, // colorkey: RGB:0xffffff
A_TEXTURE__COLORMOD_FLAT, // non-colorkey: RGB:0xffffff
A_TEXTURE__NUM
} APlatformTextureVersion;
struct APlatformTexture {
SDL_Texture* texture[A_TEXTURE__NUM];
};
extern SDL_Renderer* a__sdlRenderer;
static inline SDL_BlendMode pixelBlendToSdlBlend(void)
{
switch(a__color.blend) {
case A_COLOR_BLEND_MOD:
return SDL_BLENDMODE_MOD;
case A_COLOR_BLEND_ADD:
return SDL_BLENDMODE_ADD;
default:
return SDL_BLENDMODE_BLEND;
}
}
static inline uint8_t pixelAlphaToSdlAlpha(void)
{
switch(a__color.blend) {
case A_COLOR_BLEND_RGBA:
return (uint8_t)a__color.alpha;
case A_COLOR_BLEND_RGB25:
return SDL_ALPHA_OPAQUE / 4;
case A_COLOR_BLEND_RGB50:
return SDL_ALPHA_OPAQUE / 2;
case A_COLOR_BLEND_RGB75:
return SDL_ALPHA_OPAQUE * 3 / 4;
default:
return SDL_ALPHA_OPAQUE;
}
}
void a_platform_api__renderSetDrawColor(void)
{
if(SDL_SetRenderDrawColor(a__sdlRenderer,
(uint8_t)a__color.rgb.r,
(uint8_t)a__color.rgb.g,
(uint8_t)a__color.rgb.b,
pixelAlphaToSdlAlpha()) < 0) {
a_out__error("SDL_SetRenderDrawColor: %s", SDL_GetError());
}
}
void a_platform_api__renderSetBlendMode(void)
{
if(SDL_SetRenderDrawBlendMode(a__sdlRenderer, pixelBlendToSdlBlend()) < 0) {
a_out__error("SDL_SetRenderDrawBlendMode: %s", SDL_GetError());
}
}
void a_platform_api__drawPixel(int X, int Y)
{
if(SDL_RenderDrawPoint(a__sdlRenderer, X, Y) < 0) {
......@@ -321,156 +256,4 @@ void a_platform_api__drawCircleFilled(int X, int Y, int Radius)
a_out__error("SDL_RenderFillRects: %s", SDL_GetError());
}
}
APlatformTexture* a_platform_api__textureNew(const APixels* Pixels, unsigned Frame)
{
APlatformTexture* texture = a_mem_zalloc(sizeof(APlatformTexture));
const APixel* original = a_pixels__bufferGetStart(Pixels, Frame);
APixel* buffer = a_mem_dup(original, Pixels->bufferSize);
for(int t = 0; t < A_TEXTURE__NUM; t++) {
switch(t) {
case A_TEXTURE__NORMAL: {
for(int i = Pixels->w * Pixels->h; i--; ) {
if(original[i] != a_color__key) {
// Set full alpha for non-transparent pixel
buffer[i] |= (APixel)A__PX_MASK_A << A__PX_SHIFT_A;
}
}
} break;
case A_TEXTURE__COLORMOD_BITMAP: {
for(int i = Pixels->w * Pixels->h; i--; ) {
if(original[i] == a_color__key) {
// Set full color for transparent pixel
buffer[i] |= a_pixel_fromHex(0xffffff);
}
}
} break;
case A_TEXTURE__COLORMOD_FLAT: {
for(int i = Pixels->w * Pixels->h; i--;) {
if(original[i] != a_color__key) {
// Set full color for non-transparent pixel
buffer[i] |= a_pixel_fromHex(0xffffff);
}
}
} break;
}
SDL_Texture* tex = SDL_CreateTexture(a__sdlRenderer,
A_SDL__PIXEL_FORMAT,
SDL_TEXTUREACCESS_TARGET,
Pixels->w,
Pixels->h);
if(tex == NULL) {
A__FATAL("SDL_CreateTexture: %s", SDL_GetError());
}
if(SDL_UpdateTexture(
tex, NULL, buffer, Pixels->w * (int)sizeof(APixel)) < 0) {
A__FATAL("SDL_UpdateTexture: %s", SDL_GetError());
}
if(SDL_SetTextureBlendMode(tex, SDL_BLENDMODE_BLEND) < 0) {
a_out__error("SDL_SetTextureBlendMode: %s", SDL_GetError());
}
texture->texture[t] = tex;
}
free(buffer);
return texture;
}
void a_platform_api__textureFree(APlatformTexture* Texture)
{
if(Texture == NULL) {
return;
}
for(int t = A_TEXTURE__NUM; t--; ) {
if(Texture->texture[t]) {
SDL_DestroyTexture(Texture->texture[t]);
}
}
free(Texture);
}
void a_platform_api__textureBlit(const APlatformTexture* Texture, const APixels* Pixels, unsigned Frame, int X, int Y)
{
a_platform_api__textureBlitEx(Texture,
Pixels,
Frame,
X + Pixels->w / 2,
Y + Pixels->h / 2,
A_FIX_ONE,
0,
0,
0);
}
void a_platform_api__textureBlitEx(const APlatformTexture* Texture, const APixels* Pixels, unsigned Frame, int X, int Y, AFix Scale, unsigned Angle, int CenterX, int CenterY)
{
A_UNUSED(Frame);
SDL_Texture* tex;
SDL_BlendMode blend = pixelBlendToSdlBlend();
if(a__color.fillBlit) {
tex = Texture->texture[A_TEXTURE__COLORMOD_FLAT];
} else if(blend == SDL_BLENDMODE_MOD) {
tex = Texture->texture[A_TEXTURE__COLORMOD_BITMAP];
} else {
tex = Texture->texture[A_TEXTURE__NORMAL];
}
if(SDL_SetTextureBlendMode(tex, blend) < 0) {
a_out__error("SDL_SetTextureBlendMode: %s", SDL_GetError());
}
if(SDL_SetTextureAlphaMod(tex, pixelAlphaToSdlAlpha()) < 0) {
a_out__error("SDL_SetTextureAlphaMod: %s", SDL_GetError());
}
if(a__color.fillBlit) {
if(SDL_SetTextureColorMod(tex,
(uint8_t)a__color.rgb.r,
(uint8_t)a__color.rgb.g,
(uint8_t)a__color.rgb.b) < 0) {
a_out__error("SDL_SetTextureColorMod: %s", SDL_GetError());
}
}
SDL_Point center = {
a_fix_toInt((Pixels->w / 2 + CenterX) * Scale),
a_fix_toInt((Pixels->h / 2 + CenterY) * Scale)
};
SDL_Rect dest = {X - center.x,
Y - center.y,
a_fix_toInt(Pixels->w * Scale),
a_fix_toInt(Pixels->h * Scale)};
if(SDL_RenderCopyEx(a__sdlRenderer,
tex,
NULL,
&dest,
360 - 360 * Angle / A_FIX_ANGLES_NUM,
&center,
SDL_FLIP_NONE) < 0) {
a_out__error("SDL_RenderCopyEx: %s", SDL_GetError());
}
if(a__color.fillBlit) {
if(SDL_SetTextureColorMod(tex, 0xff, 0xff, 0xff) < 0) {
a_out__error("SDL_SetTextureColorMod: %s", SDL_GetError());
}
}
}
#endif // A_CONFIG_LIB_RENDER_SDL
/*
Copyright 2019 Alex Margarit <alex@alxm.org>
This file is part of a2x, a C video game framework.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "platform/graphics/a_sdl_draw.p.h"
......@@ -619,4 +619,63 @@ void a_platform_api__screenMouseCursorSet(bool Show)
a_out__error("SDL_ShowCursor: %s", SDL_GetError());
}
}
#if A_CONFIG_LIB_RENDER_SDL
int a_platform_sdl_video__pixelBlendToSdlBlend(void)
{
switch(a__color.blend) {
case A_COLOR_BLEND_MOD:
return SDL_BLENDMODE_MOD;
case A_COLOR_BLEND_ADD:
return SDL_BLENDMODE_ADD;
default:
return SDL_BLENDMODE_BLEND;
}
}
uint8_t a_platform_sdl_video__pixelAlphaToSdlAlpha(void)
{
switch(a__color.blend) {
case A_COLOR_BLEND_RGBA:
return (uint8_t)a__color.alpha;
case A_COLOR_BLEND_RGB25:
return SDL_ALPHA_OPAQUE / 4;
case A_COLOR_BLEND_RGB50:
return SDL_ALPHA_OPAQUE / 2;
case A_COLOR_BLEND_RGB75:
return SDL_ALPHA_OPAQUE * 3 / 4;
default:
return SDL_ALPHA_OPAQUE;
}
}
void a_platform_api__renderSetDrawColor(void)
{
if(SDL_SetRenderDrawColor(
a__sdlRenderer,
(uint8_t)a__color.rgb.r,
(uint8_t)a__color.rgb.g,
(uint8_t)a__color.rgb.b,
a_platform_sdl_video__pixelAlphaToSdlAlpha()) < 0) {
a_out__error("SDL_SetRenderDrawColor: %s", SDL_GetError());
}
}
void a_platform_api__renderSetBlendMode(void)
{
SDL_BlendMode blend =
(SDL_BlendMode)a_platform_sdl_video__pixelBlendToSdlBlend();
if(SDL_SetRenderDrawBlendMode(a__sdlRenderer, blend) < 0) {
a_out__error("SDL_SetRenderDrawBlendMode: %s", SDL_GetError());
}
}
#endif // A_CONFIG_LIB_RENDER_SDL
#endif // A_CONFIG_LIB_SDL
......@@ -18,7 +18,7 @@
#pragma once
#include "platform/a_sdl_video.p.h"
#include "platform/graphics/a_sdl_video.p.h"
#if A_CONFIG_LIB_SDL == 2
#if A_CONFIG_SCREEN_BPP == 16
......@@ -38,3 +38,6 @@
extern void a_platform_sdl_video__init(void);
extern void a_platform_sdl_video__uninit(void);
extern int a_platform_sdl_video__pixelBlendToSdlBlend(void);
extern uint8_t a_platform_sdl_video__pixelAlphaToSdlAlpha(void);
......@@ -110,14 +110,14 @@ void scan_line(int Index, AVectorInt ScrP1, AVectorInt ScrP2, AVectorFix SprP1,
#define A__BLEND_SETUP
#define A__PIXEL_SETUP
#define A__PIXEL_PARAMS , *src
#include "platform/a_software_blit.inc.c"
#include "platform/graphics/a_software_blit.inc.c"
#define A__BLEND plain
#define A__FILL flat
#define A__BLEND_SETUP const APixel color = a__color.pixel;
#define A__PIXEL_SETUP
#define A__PIXEL_PARAMS , color
#include "platform/a_software_blit.inc.c"
#include "platform/graphics/a_software_blit.inc.c"
#define A__BLEND rgba
#define A__FILL data
......@@ -128,7 +128,7 @@ void scan_line(int Index, AVectorInt ScrP1, AVectorInt ScrP2, AVectorFix SprP1,
}
#define A__PIXEL_SETUP const ARgb rgb = a_pixel_toRgb(*src);
#define A__PIXEL_PARAMS , &rgb, alpha
#include "platform/a_software_blit.inc.c"
#include "platform/graphics/a_software_blit.inc.c"
#define A__BLEND rgba
#define A__FILL flat
......@@ -140,91 +140,91 @@ void scan_line(int Index, AVectorInt ScrP1, AVectorInt ScrP2, AVectorFix SprP1,
}
#define A__PIXEL_SETUP
#define A__PIXEL_PARAMS , &rgb, alpha
#include "platform/a_software_blit.inc.c"
#include "platform/graphics/a_software_blit.inc.c"
#define A__BLEND rgb25
#define A__FILL data
#define A__BLEND_SETUP
#define A__PIXEL_SETUP const ARgb rgb = a_pixel_toRgb(*src);
#define A__PIXEL_PARAMS , &rgb
#include "platform/a_software_blit.inc.c"
#include "platform/graphics/a_software_blit.inc.c"