C

Qt Quick Ultralite sprite_animations Example

# Copyright (C) 2026 The Qt Company Ltd.
# SPDX-License-Identifier: LicenseRef-Qt-Commercial
cmake_minimum_required(VERSION 3.21.1)

project(sprite_animations VERSION 0.0.1 LANGUAGES C CXX ASM)

find_package(QulApp)

# STM32F7/STM32H7/RH850 and traveo-t2g boards use a JPEG image sequence
# decoded via a hardware/software JPEG decoder (AnimatedSpriteDirectory);
# everything else uses a single pre-baked PNG sprite sheet (AnimatedSprite).
set(SPRITE_ANIMATIONS_USES_JPEG FALSE)
if(QUL_PLATFORM MATCHES "^stm32[fh]7" OR QUL_PLATFORM MATCHES "^tviic2d6m[^-]*-baremetal" OR QUL_PLATFORM MATCHES "rh850-d1m1a-baremetal")
    set(SPRITE_ANIMATIONS_USES_JPEG TRUE)
endif()

if(QUL_PLATFORM MATCHES "^tviic2d6m[^-]*-baremetal")
    # In CI we test with the 500-BGA variant with graphics driver TVII_GRAPHICS_DRIVER_DIR_1_1_0_4M6M
    # (infineon-traveo-t2g-cyt4dn-baremetal-500-bga-windows-ghs-arm)
    # and to be able to build the imagedecoder backend an SDL upgrade is required.
    if(QUL_TVIIC2D6M_BOARD_REVISION STREQUAL "500-BGA")
        return()
    endif()
    if(ARMGCC)
        # The JPEG driver does not support ARMGCC at the moment.
        return()
    endif()
endif()

if(QUL_PLATFORM MATCHES "autosar")
    qul_add_library(sprite_animations)
else()
    qul_add_executable(sprite_animations)
endif()

if(SPRITE_ANIMATIONS_USES_JPEG)
    # The JPEG variants use a hand-written main() that sets up the board's decoder.
    target_sources(sprite_animations PRIVATE os/${QUL_OS_LOWERCASE}/main.cpp)

    set(SPRITE_ANIMATIONS_JPEG_FILES
        qt-image-sequence/00.jpg
        qt-image-sequence/01.jpg
        qt-image-sequence/02.jpg
        qt-image-sequence/03.jpg
        qt-image-sequence/04.jpg
        qt-image-sequence/05.jpg
        qt-image-sequence/06.jpg
        qt-image-sequence/07.jpg
        qt-image-sequence/08.jpg
        qt-image-sequence/09.jpg
        qt-image-sequence/10.jpg
        qt-image-sequence/11.jpg
        qt-image-sequence/12.jpg
        qt-image-sequence/13.jpg
        qt-image-sequence/14.jpg
        qt-image-sequence/15.jpg
    )
    set_source_files_properties(${SPRITE_ANIMATIONS_JPEG_FILES} PROPERTIES
        QUL_RESOURCE_ANIMATED_SPRITE ON
        QUL_RESOURCE_KEEP_RAW_DATA ON
    )

    qul_add_qml_module(sprite_animations
        URI SpriteAnimationsApp
        QML_FILES ToggleButton.qml sprite_animations_jpeg.qml
        RESOURCES ${SPRITE_ANIMATIONS_JPEG_FILES}
    )

    if(QUL_PLATFORM MATCHES "^tviic2d6m[^-]*-baremetal")
        # enough size to contain four decoded images, accounting for
        # asynchronous OTF rendering: UL-10814
        qul_set_maximum_resource_cache_size(sprite_animations CACHE_SIZE 614400)
    else()
        # enough size to contain one decoded image
        qul_set_maximum_resource_cache_size(sprite_animations CACHE_SIZE 153600)
    endif()

    if(QUL_PLATFORM MATCHES "^stm32[fh]7")
        # STM32F7/STM32H7 boards use JPEG decoder
        if(QUL_PLATFORM MATCHES "^stm32f7")
            set(STM32XX "stm32f7")

            target_sources(sprite_animations PRIVATE
                ${QUL_BOARD_SDK_DIR}/Drivers/STM32F7xx_HAL_Driver/Src/stm32f7xx_hal_jpeg.c
                ../imagedecoder/stm/${STM32XX}/stm32f7xx_hal_msp.c
            )

            target_compile_definitions(sprite_animations PRIVATE USE_DMA_BASED_JPEG_DECODING)

        elseif(QUL_PLATFORM MATCHES "^stm32h7")
            set(STM32XX "stm32h7")

            target_sources(sprite_animations PRIVATE
                ${QUL_BOARD_SDK_DIR}/Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_jpeg.c
                ../imagedecoder/stm/${STM32XX}/stm32h7xx_hal_msp.c
            )
        endif()

        target_sources(sprite_animations PRIVATE
            ../imagedecoder/stm/${STM32XX}/board_config.cpp
            ../imagedecoder/stm/${STM32XX}/buffer_config.cpp
            ../imagedecoder/stm/stmimagedecoder.cpp
            ../imagedecoder/common/jpeg.cpp
            ../imagedecoder/3rdparty/stm/Utilities/JPEG/jpeg_utils.c
        )

        target_include_directories(sprite_animations PRIVATE
            ${QUL_BOARD_SDK_DIR}/Utilities/JPEG
            ../imagedecoder/stm/${STM32XX}
            ../imagedecoder/stm
            ../imagedecoder
        )

        target_compile_definitions(sprite_animations PRIVATE
            USE_JPEG_DECODER=1
            PLATFORM_OS=${QUL_OS_LOWERCASE}
        )

        target_link_libraries(sprite_animations PRIVATE Qul::PlatformBSPConfig)

        if(NOT IAR)
            # Required for SDK code to build
            target_compile_options(sprite_animations PRIVATE
                -Wno-unused-parameter
            )
        endif()
    elseif(QUL_PLATFORM MATCHES "^tviic2d6m[^-]*-baremetal")
        set(TRAVEO_T2G_IMAGEDECODER_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../imagedecoder/traveo-t2g")
        include("${TRAVEO_T2G_IMAGEDECODER_SOURCE_DIR}/tvii_jpeg_driver_lib.cmake") # will provide `TVII_JPEG_DRIVER_LIB`.

        target_sources(sprite_animations PRIVATE
            ../imagedecoder/traveo-t2g/board_config.cpp
            ../imagedecoder/traveo-t2g/traveot2gimagedecoder.cpp
            ../imagedecoder/traveo-t2g/tvii_jpeg.c
            ../imagedecoder/common/jpeg.cpp
        )

        list(APPEND CMAKE_MODULE_PATH ${QUL_PLATFORM_TARGET_DIR}/../common/cmake/modules)
        # Old path needed for platform compatibility checks after UL-5159 (renamed folder from tvii-shared to common)
        list(APPEND CMAKE_MODULE_PATH ${QUL_PLATFORM_TARGET_DIR}/../tvii-shared/cmake/modules)
        find_package(TVII-SDK REQUIRED COMPONENTS basic_graphics util freetype)

        target_include_directories(sprite_animations PRIVATE
            ../imagedecoder/
            ../imagedecoder/traveo-t2g/
            ${TVII_JPEG_DRIVER_DIR}/Source/jpgdec/include
            ${TVII_SDK_INCLUDE_DIRS}
        )

        target_link_libraries(sprite_animations PRIVATE Qul::PlatformBSPConfig ${TVII_JPEG_DRIVER_LIB})
        if(GREENHILLS)
            target_link_libraries(sprite_animations PRIVATE -T ${CMAKE_CURRENT_SOURCE_DIR}/../imagedecoder/traveo-t2g/JPEGDEC_register_map.ld)
        endif()

        if(IAR)
            target_compile_options(sprite_animations PRIVATE --diag_suppress=Pe940) # Pe940 missing return statement at end of non-void function (graphics driver 1.2.1)
        endif()
    elseif(QUL_PLATFORM MATCHES "rh850-d1m1a-baremetal")
        target_sources(sprite_animations PRIVATE
            ${CMAKE_CURRENT_SOURCE_DIR}/../imagedecoder/renesas-rh850/board_config.cpp
            ${CMAKE_CURRENT_SOURCE_DIR}/../imagedecoder/renesas-rh850/rh850imagedecoder.cpp
            ${CMAKE_CURRENT_SOURCE_DIR}/../imagedecoder/renesas-rh850/rh850_jpeg.cpp
            ${CMAKE_CURRENT_SOURCE_DIR}/../imagedecoder/common/jpeg.cpp
        )

        target_include_directories(sprite_animations PRIVATE
            ${CMAKE_CURRENT_SOURCE_DIR}/../imagedecoder/
            ${CMAKE_CURRENT_SOURCE_DIR}/../imagedecoder/renesas-rh850/
        )

        target_compile_definitions(sprite_animations PRIVATE
            USE_OUTPUT_SPLIT_MODE
            DECODE_BUFFER_PIXEL_LINES=16
            CHROMA_SUBSAMPLING=R_JCUA_JPEG_FORMAT_YCBCR420
        )

        target_link_libraries(sprite_animations PRIVATE Qul::PlatformBSPConfig)
    endif()
else()
    set_source_files_properties(qt-image-sequence.png PROPERTIES
        QUL_RESOURCE_ANIMATED_SPRITE_FRAME_WIDTH 180
        QUL_RESOURCE_ANIMATED_SPRITE_FRAME_HEIGHT 160
    )

    qul_add_qml_module(sprite_animations
        URI SpriteAnimationsApp
        QML_FILES sprite_animations.qml ToggleButton.qml
        RESOURCES qt-image-sequence.png
    )

    app_target_default_entrypoint(sprite_animations sprite_animations MODULE SpriteAnimationsApp)
endif()

app_target_setup_os(sprite_animations)