diff --git a/CMakeLists.txt b/CMakeLists.txt index b9294e2..acdf7fd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,46 +1,92 @@ -cmake_minimum_required(VERSION 3.6) +cmake_minimum_required(VERSION 3.16) project(Tilengine) +# set an option to use libpng from the system, otherwise use bundled stb_image +option(TLN_OPTION_LIBPNG "Use the system libpng" ON) +option(TLN_OPTION_BUILD_LIBPNG "Build libpng from source" OFF) + +# set an option to make the examples +option(TLN_OPTION_SAMPLES "Build the examples" OFF) file(GLOB SOURCES "src/*.c" ) - # main library list(REMOVE_ITEM SOURCES "src/Test.c") add_library(${PROJECT_NAME} ${SOURCES}) if (UNIX AND NOT APPLE) set(CMAKE_C_FLAGS "-m64 -msse2") -elseif (UNIX AND APPLE) - target_link_libraries(${PROJECT_NAME} PRIVATE "framework") +endif() + +if (TLN_OPTION_LIBPNG) + # this project needs png, if png is not found, let's use fetch content + find_package(PNG QUIET) + if (NOT PNG_FOUND AND TLN_OPTION_BUILD_LIBPNG) + include(FetchContent) + FetchContent_Declare( + libpng + GIT_REPOSITORY https://github.com/pnggroup/libpng.git + GIT_TAG v1.6.44 + ) + FetchContent_MakeAvailable(libpng) + set(PNG_LIBRARIES png_static) + add_definitions(-DTLN_HAVE_PNG) + target_link_libraries(${PROJECT_NAME} PRIVATE ${PNG_LIBRARIES}) + endif() + if (NOT PNG_FOUND AND NOT TLN_OPTION_BUILD_LIBPNG) + # clear the PNG_LIBRARY variable + unset(PNG_LIBRARY CACHE) + endif() + if (PNG_FOUND) + add_definitions(-DTLN_HAVE_PNG) + target_include_directories(${PROJECT_NAME} PRIVATE ${PNG_INCLUDE_DIRS}) + target_link_libraries(${PROJECT_NAME} PRIVATE ${PNG_LIBRARIES}) + endif() endif() target_link_libraries(${PROJECT_NAME} PRIVATE "c") target_link_libraries(${PROJECT_NAME} PRIVATE "z") -target_link_libraries(${PROJECT_NAME} PRIVATE "png") -find_package(SDL2 REQUIRED) -target_link_libraries(${PROJECT_NAME} PRIVATE ${SDL2_LIBRARIES}) +if (TILENGINE_SAMPLES) + find_package(SDL2 REQUIRED) + target_link_libraries(${PROJECT_NAME} PRIVATE ${SDL2_LIBRARIES}) + add_definitions(-DTLN_HAVE_SDL2) +else() + add_definitions(-DTLN_EXCLUDE_WINDOW) +endif() target_include_directories(${PROJECT_NAME} PRIVATE include) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99 -O2 -fpic -DLIB_EXPORTS") -set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-unused-result -Wno-format-truncation") +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-unused-result") + +# gcc specific +if (UNIX AND NOT APPLE) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-format-truncation") +endif() file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/include/Tilengine.h DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) -# test executable -add_executable(Test src/Test.c) -target_include_directories(Test PRIVATE include) -target_link_libraries(Test PRIVATE "Tilengine") -target_link_libraries(Test PRIVATE "c") -target_link_libraries(Test PRIVATE "z") -target_link_libraries(Test PRIVATE "png") -target_link_libraries(Test PRIVATE "m") - -# samples -add_subdirectory(samples) \ No newline at end of file +if (TILENGINE_SAMPLES) + # test executable + add_executable(Test src/Test.c) + target_include_directories(Test PRIVATE include) + target_link_libraries(Test PRIVATE "Tilengine") + target_link_libraries(Test PRIVATE "c") + target_link_libraries(Test PRIVATE "z") + if (TLN_OPTION_LIBPNG) + target_include_directories(Test PRIVATE ${PNG_INCLUDE_DIRS}) + target_link_libraries(Test PRIVATE ${PNG_LIBRARIES}) + endif() + target_link_libraries(Test PRIVATE ${PNG_LIBRARIES}) + target_link_libraries(Test PRIVATE "m") +endif() + +if (TLN_OPTION_SAMPLES) + # samples + add_subdirectory(samples) +endif() diff --git a/README.md b/README.md index 1d371a8..68f4f6b 100644 --- a/README.md +++ b/README.md @@ -5,6 +5,13 @@ Tilengine is an open source, cross-platform 2D graphics engine for creating classic/retro games with tile maps, sprites and palettes. Its unique scanline-based rendering algorithm makes raster effects a core feature, a technique used by many games running on real 2D graphics chips. +# This fork + +This fork, in the macos branch, +- allows the use of a bundled stb_image instead of libpng via -DTLN_OPTION_LIBPNG=ON +- only uses SDL2 if the -DTLN_OPTION_SAMPLES=ON flag is set +- fixes macOS setting issues in the CMakeLists.txt + http://www.tilengine.org # Contents diff --git a/samples/Actor.c b/samples/Actor.c index 221a8e9..5753fd1 100644 --- a/samples/Actor.c +++ b/samples/Actor.c @@ -6,7 +6,7 @@ /* local variables */ static Actor* actors; static int count = 0; -static unsigned int time; +static unsigned int actor_time; /* local prototypes */ static void TasksActor (Actor* actor); @@ -112,7 +112,7 @@ void TasksActors (unsigned int t) if (!actors) return; - time = t; + actor_time = t; for (c=0; ctimers[timer] = time + timeout; + actor->timers[timer] = actor_time + timeout; } /* gets generic timeout ended */ bool GetActorTimeout (Actor* actor, int timer) { - return time >= actor->timers[timer]; + return actor_time >= actor->timers[timer]; } /* TasksActor */ diff --git a/samples/CMakeLists.txt b/samples/CMakeLists.txt index 241c8e0..492d4f5 100644 --- a/samples/CMakeLists.txt +++ b/samples/CMakeLists.txt @@ -19,7 +19,12 @@ find_package(SDL2 REQUIRED) link_libraries(${SDL2_LIBRARIES}) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99 -O2 -fpic -DLIB_EXPORTS") -set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-unused-result -Wno-format-truncation") +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-unused-result") + +# gcc specific +if (UNIX AND NOT APPLE) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-format-truncation") +endif() file(COPY assets DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) diff --git a/samples/Racer.c b/samples/Racer.c index 8a114c2..b25c937 100644 --- a/samples/Racer.c +++ b/samples/Racer.c @@ -50,7 +50,7 @@ int pos; int speed; int last_tree; unsigned int frame; -unsigned int time; +unsigned int racer_time; int pan = 0; static void raster_callback (int line); @@ -81,7 +81,7 @@ int main (int argc, char* argv[]) while (TLN_ProcessWindow ()) { /* timekeeper */ - time = frame; + racer_time = frame; TLN_SetLayerPosition (LAYER_PLAYFIELD, 56,72); if (pos - last_tree >= 100) @@ -92,7 +92,7 @@ int main (int argc, char* argv[]) } /* input */ - if ((time & 0x07) == 0) + if ((racer_time & 0x07) == 0) { if (TLN_GetInput (INPUT_UP) && speed < MAX_SPEED) speed++; @@ -107,10 +107,10 @@ int main (int argc, char* argv[]) /* actores */ pos += speed; - TasksActors (time); + TasksActors (racer_time); /* render to window */ - TLN_DrawFrame (time); + TLN_DrawFrame (racer_time); frame++; } diff --git a/samples/Shooter.c b/samples/Shooter.c index eb3bba8..ebf4eb3 100644 --- a/samples/Shooter.c +++ b/samples/Shooter.c @@ -60,7 +60,7 @@ int pos_foreground[3] = {0}; int pos_background[3] = {0}; int inc_background[3] = {0}; unsigned int frame; -unsigned int time; +unsigned int racer_time; uint8_t sky1[3] = {107,205,255}; uint8_t sky2[3] = {255,242,167}; @@ -97,48 +97,111 @@ static void FreeLayer (int index) TLN_DeleteTilemap (layer->tilemap); } +void ShooterInit(const char* resourceRoot) +{ + int c; + + /* setup engine */ + TLN_Init (WIDTH,HEIGHT, MAX_LAYER, MAX_ACTOR, 0); + TLN_SetRasterCallback (raster_callback); + TLN_SetBGColor (136,238,204); + + /* load resources*/ + TLN_SetLoadPath (resourceRoot); + spritesets[SPRITESET_MAIN] = TLN_LoadSpriteset ("FireLeo"); + spritesets[SPRITESET_HELLARM] = TLN_LoadSpriteset ("HellArm"); + LoadLayer (LAYER_FOREGROUND, "TF4_fg1"); + LoadLayer (LAYER_BACKGROUND, "TF4_bg1"); + + /* create sequences from sprite names */ + sequences[SEQ_CLAW ] = TLN_CreateSpriteSequence (NULL, spritesets[SPRITESET_MAIN], "claw", 4); + sequences[SEQ_BLADE1] = TLN_CreateSpriteSequence (NULL, spritesets[SPRITESET_MAIN], "bladeb", 2); + sequences[SEQ_BLADE2] = TLN_CreateSpriteSequence (NULL, spritesets[SPRITESET_MAIN], "blades", 2); + sequences[SEQ_EXPLO1] = TLN_CreateSpriteSequence (NULL, spritesets[SPRITESET_MAIN], "explb", 3); + sequences[SEQ_EXPLO2] = TLN_CreateSpriteSequence (NULL, spritesets[SPRITESET_MAIN], "expls", 2); + + /* create actors */ + CreateActors (MAX_ACTOR); + CreateShip (); + BuildSinTable (); + + /* compute increments for background scroll*/ + inc_background[0] = float2fix(1.0f); /* 1.0 pixels/frame */ + inc_background[1] = float2fix(1.2f); /* 1.2 pixels/frame*/ + inc_background[2] = float2fix(8.0f); /* 8.0 pixels/frame*/ + + /* initial colors */ + for (c=0; c<3; c++) + { + sky_hi[c] = sky1[c]; + sky_lo[c] = sky2[c]; + } + for (c=0; c=PAL_T0 && racer_time<=PAL_T1 && (racer_time&0x07)==0) + { + /* sky color */ + for (c=0; c<3; c++) + { + sky_hi[c] = lerp(racer_time, PAL_T0,PAL_T1, sky1[c], sky3[c]); + sky_lo[c] = lerp(racer_time, PAL_T0,PAL_T1, sky2[c], sky4[c]); + } + + for (c=0; c=PAL_T0 && time<=PAL_T1 && (time&0x07)==0) - { - /* sky color */ - for (c=0; c<3; c++) - { - sky_hi[c] = lerp(time, PAL_T0,PAL_T1, sky1[c], sky3[c]); - sky_lo[c] = lerp(time, PAL_T0,PAL_T1, sky2[c], sky4[c]); - } - - for (c=0; clayers[nlayer]; /* check proper config */ - if (layer->type == LAYER_TILE && layer->tilemap != NULL || layer->type == LAYER_BITMAP && layer->bitmap != NULL || layer->type == LAYER_OBJECT && layer->objects != NULL) + if ((layer->type == LAYER_TILE && layer->tilemap != NULL) || + (layer->type == LAYER_BITMAP && layer->bitmap != NULL) || + (layer->type == LAYER_OBJECT && layer->objects != NULL)) { layer->ok = true; - TLN_SetLastError(TLN_ERR_IDX_LAYER); + TLN_SetLastError(TLN_ERR_OK); return true; } diff --git a/src/Layer.h b/src/Layer.h index ff9a4eb..1d83553 100644 --- a/src/Layer.h +++ b/src/Layer.h @@ -77,4 +77,4 @@ Layer; Layer* GetLayer(int index); -#endif \ No newline at end of file +#endif diff --git a/src/LoadBitmap.c b/src/LoadBitmap.c index 0060258..9387d32 100644 --- a/src/LoadBitmap.c +++ b/src/LoadBitmap.c @@ -12,11 +12,16 @@ #include #include "Tilengine.h" #include "LoadFile.h" -#include "png.h" #include "DIB.h" #include "Bitmap.h" #include "Palette.h" +#if TLN_HAVE_PNG +#include "png.h" +#else +#include "../../../src/Providers/Texture/stb_image.h" +#endif + static TLN_Bitmap LoadPNG (const char* filename); static TLN_Bitmap LoadBMP (const char* filename); @@ -114,7 +119,8 @@ static TLN_Bitmap Convert24ToIndexed(TLN_Bitmap source) for (x = 0; x < source->width; x += 1) { uint32_t value = PackRGB32(srccolor->r, srccolor->g, srccolor->b); - *dstcolor = set_get_index(&colors, value) + 1; + uint8_t idx = set_get_index(&colors, value); + *dstcolor = !idx ? 0 : idx + 1; srccolor += 1; dstcolor += 1; } @@ -257,6 +263,34 @@ TLN_Bitmap TLN_LoadBitmap (const char* filename) return bitmap; } +#if !TLN_HAVE_PNG + +static TLN_Bitmap LoadPNG (const char* filename) +{ + TLN_Bitmap bitmap = NULL; + int width, height, bpp; + uint8_t* data = stbi_load (filename, &width, &height, &bpp, 0); + if (data) + { + bitmap = TLN_CreateBitmap (width, height, bpp * 8); + if (bitmap) + { + int pitch = TLN_GetBitmapPitch (bitmap); + uint8_t* dst = TLN_GetBitmapPtr (bitmap, 0, 0); + int y; + for (y=0; yframebuffer = framebuffer; } +#endif + void CRTIncreaseGlow(CRTHandler crt) { if (crt != NULL && crt->glow < 255) @@ -162,9 +169,10 @@ void CRTSetBlur(CRTHandler crt, bool blur) void CRTDelete(CRTHandler crt) { +#if TLN_HAVE_SDL2 if (crt != NULL) SDL_DestroyTexture(crt->overlay); - +#endif free(crt); } @@ -200,6 +208,8 @@ static void blit(const uint8_t* srcptr, uint8_t* dstptr, int srcpitch, int lines } } +#if TLN_HAVE_SDL2 + static SDL_Texture* create_tiled_texture(SDL_Renderer* renderer, int width, int height, int tile_width, int tile_height, const uint8_t* tile_data) { SDL_Surface* surface = SDL_CreateRGBSurface(0, width, height, 32, 0, 0, 0, 0); @@ -222,3 +232,6 @@ static SDL_Texture* create_tiled_texture(SDL_Renderer* renderer, int width, int SDL_FreeSurface(surface); return texture; } + +#endif + diff --git a/src/crt.h b/src/crt.h index 085bfa2..2726ed1 100644 --- a/src/crt.h +++ b/src/crt.h @@ -2,7 +2,10 @@ #define _CRT_H #include + +#if TILEENGINE_HAVE_SDL2 #include "SDL2/SDL.h" +#endif typedef enum { @@ -18,9 +21,12 @@ typedef struct _CRTHandler* CRTHandler; extern "C"{ #endif - CRTHandler CRTCreate(SDL_Renderer* renderer, SDL_Texture* framebuffer, CRTType type, int wnd_width, int wnd_height, bool blur); +#if TILEENGINE_HAVE_SDL2 + CRTHandler CRTCreate(SDL_Renderer* renderer, SDL_Texture* framebuffer, + CRTType type, int wnd_width, int wnd_height, bool blur); void CRTDraw(CRTHandler crt, void* pixels, int pitch, SDL_Rect* dstrect); void CRTSetRenderTarget(CRTHandler crt, SDL_Texture* framebuffer); +#endif void CRTIncreaseGlow(CRTHandler crt); void CRTDecreaseGlow(CRTHandler crt); void CRTSetBlur(CRTHandler crt, bool blur); @@ -30,4 +36,4 @@ extern "C"{ } #endif -#endif \ No newline at end of file +#endif