Use TouchGFX
This commit is contained in:
		
							
								
								
									
										242
									
								
								TouchGFX/generated/simulator/gcc/Makefile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										242
									
								
								TouchGFX/generated/simulator/gcc/Makefile
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,242 @@
 | 
			
		||||
# Get identification of this system
 | 
			
		||||
ifeq ($(OS),Windows_NT)
 | 
			
		||||
UNAME := MINGW32_NT-6.2
 | 
			
		||||
else
 | 
			
		||||
UNAME := $(shell uname -s)
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
board_name := $(UNAME)
 | 
			
		||||
 | 
			
		||||
.PHONY: all clean assets
 | 
			
		||||
 | 
			
		||||
# Directories containing application-specific source and header files.
 | 
			
		||||
# Additional components can be added to this list. make will look for
 | 
			
		||||
# source files recursively in comp_name/src and setup an include directive
 | 
			
		||||
# for comp_name/include.
 | 
			
		||||
components := gui simulator generated/gui_generated generated/simulator
 | 
			
		||||
 | 
			
		||||
# Location of folder containing bmp/png files.
 | 
			
		||||
asset_images_input := assets/images
 | 
			
		||||
 | 
			
		||||
# Location of folder to search for ttf font files
 | 
			
		||||
asset_fonts_input := assets/fonts
 | 
			
		||||
 | 
			
		||||
# Location of folder where the texts.xml is placed
 | 
			
		||||
asset_texts_input := assets/texts
 | 
			
		||||
 | 
			
		||||
# Location of folder where video files are places
 | 
			
		||||
asset_videos_input := assets/videos
 | 
			
		||||
 | 
			
		||||
build_root_path := build
 | 
			
		||||
object_output_path := $(build_root_path)/$(board_name)
 | 
			
		||||
binary_output_path := $(build_root_path)/bin
 | 
			
		||||
 | 
			
		||||
# Location of output folders where autogenerated code from assets is placed
 | 
			
		||||
asset_root_path := generated
 | 
			
		||||
asset_images_output := $(asset_root_path)/images
 | 
			
		||||
asset_fonts_output := $(asset_root_path)/fonts
 | 
			
		||||
asset_texts_output := $(asset_root_path)/texts
 | 
			
		||||
asset_videos_output := $(asset_root_path)/videos
 | 
			
		||||
 | 
			
		||||
#include application specific configuration
 | 
			
		||||
include config/gcc/app.mk
 | 
			
		||||
 | 
			
		||||
### END OF USER SECTION. THE FOLLOWING SHOULD NOT BE MODIFIED ###
 | 
			
		||||
 | 
			
		||||
ifeq ($(UNAME), Linux)
 | 
			
		||||
library_path := $(touchgfx_path)/3rdparty/libjpeg/lib/linux $(touchgfx_path)/lib/linux $(ADDITIONAL_LIBRARY_PATHS)
 | 
			
		||||
libraries := touchgfx SDL2 SDL2_image jpeg rt m pthread dl $(ADDITIONAL_LIBRARIES)
 | 
			
		||||
libstart := -Wl,--start-group
 | 
			
		||||
libend := -Wl,--end-group
 | 
			
		||||
libextra :=
 | 
			
		||||
library_includes += $(touchgfx_path)/3rdparty/libjpeg/include
 | 
			
		||||
linker_options_local := -Xlinker -rpath -Xlinker $(touchgfx_path)/3rdparty/libjpeg/lib/linux
 | 
			
		||||
resource_file :=
 | 
			
		||||
imageconvert_executable := $(touchgfx_path)/framework/tools/imageconvert/build/linux/imageconvert.out
 | 
			
		||||
fontconvert_executable := $(touchgfx_path)/framework/tools/fontconvert/build/linux/fontconvert.out
 | 
			
		||||
simulator_executable := simulator.out
 | 
			
		||||
linker_options += -static-libgcc -Xlinker --no-as-needed
 | 
			
		||||
else
 | 
			
		||||
sdl_library_path := $(touchgfx_path)/lib/sdl2/win32
 | 
			
		||||
jpeg_library_path := $(touchgfx_path)/3rdparty/libjpeg/lib/win32
 | 
			
		||||
library_path := $(sdl_library_path) $(jpeg_library_path) $(touchgfx_path)/lib/win/mingw32 $(ADDITIONAL_LIBRARY_PATHS)
 | 
			
		||||
libraries := touchgfx SDL2 SDL2_image jpeg-8 m pthread mingw32 $(ADDITIONAL_LIBRARIES)
 | 
			
		||||
libstart := -Wl,--start-group
 | 
			
		||||
libend := -Wl,--end-group
 | 
			
		||||
libextra := -Wl,--subsystem,windows
 | 
			
		||||
library_includes += $(touchgfx_path)/framework/include/platform/hal/simulator/sdl2/vendor $(touchgfx_path)/3rdparty/libjpeg/include
 | 
			
		||||
resource_file := generated/simulator/touchgfx.res
 | 
			
		||||
imageconvert_executable := $(touchgfx_path)/framework/tools/imageconvert/build/win/imageconvert.out
 | 
			
		||||
fontconvert_executable := $(touchgfx_path)/framework/tools/fontconvert/build/win/fontconvert.out
 | 
			
		||||
simulator_executable := simulator.exe
 | 
			
		||||
$(resource_file): $(resource_file:%.res=%.rc) $(resource_file:%.res=%.ico)
 | 
			
		||||
	@echo Creating Windows resource file with program icon
 | 
			
		||||
	@windres $(resource_file:%.res=%.rc) -O coff -o $@
 | 
			
		||||
linker_options += -static-libgcc -static-libstdc++
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
c_compiler           := g++
 | 
			
		||||
c_compiler_options   += -DSIMULATOR='' -g
 | 
			
		||||
cpp_compiler         := g++
 | 
			
		||||
cpp_compiler_options += -g -DSIMULATOR='' -DENABLE_LOG
 | 
			
		||||
linker               := g++
 | 
			
		||||
 | 
			
		||||
WARN = error all extra write-strings init-self cast-qual \
 | 
			
		||||
       pointer-arith strict-aliasing format=2 uninitialized \
 | 
			
		||||
       missing-declarations no-long-long no-unused-parameter \
 | 
			
		||||
       no-variadic-macros no-format-extra-args \
 | 
			
		||||
       no-conversion no-overloaded-virtual
 | 
			
		||||
CXXWARN = non-virtual-dtor ctor-dtor-privacy
 | 
			
		||||
 | 
			
		||||
c_compiler_options_local   += -pedantic $(addprefix -W,$(WARN))
 | 
			
		||||
cpp_compiler_options_local += -pedantic $(addprefix -W,$(WARN) $(CXXWARN))
 | 
			
		||||
 | 
			
		||||
#include everything + specific vendor folders
 | 
			
		||||
framework_includes := $(touchgfx_path)/framework/include
 | 
			
		||||
 | 
			
		||||
#only take in the source we want to build for this sim
 | 
			
		||||
framework_files := $(touchgfx_path)/framework/source/platform/driver/touch/SDL2TouchController.cpp
 | 
			
		||||
framework_source := $(touchgfx_path)/framework/source/platform/hal/simulator/sdl2
 | 
			
		||||
 | 
			
		||||
#this needs to change when assset include folder changes.
 | 
			
		||||
all_components := $(components) \
 | 
			
		||||
	$(asset_fonts_output) \
 | 
			
		||||
	$(asset_images_output) \
 | 
			
		||||
	$(asset_texts_output) \
 | 
			
		||||
	$(asset_videos_output)
 | 
			
		||||
 | 
			
		||||
#keep framework include and source out of this
 | 
			
		||||
include_paths := $(library_includes) $(foreach comp, $(all_components), $(comp)/include) $(framework_includes) $(ADDITIONAL_INCLUDE_PATHS)
 | 
			
		||||
source_paths = $(foreach comp, $(all_components), $(comp)/src) $(framework_source) simulator
 | 
			
		||||
 | 
			
		||||
# Finds files that matches the specified pattern. The directory list
 | 
			
		||||
# is searched recursively. It is safe to invoke this function with an
 | 
			
		||||
# empty list of directories.
 | 
			
		||||
#
 | 
			
		||||
# Param $(1): List of directories to search
 | 
			
		||||
# Param $(2): The file pattern to search for
 | 
			
		||||
define find
 | 
			
		||||
	$(foreach dir,$(1),$(foreach d,$(wildcard $(dir)/*),\
 | 
			
		||||
		$(call find,$(d),$(2))) $(wildcard $(dir)/$(strip $(2))))
 | 
			
		||||
endef
 | 
			
		||||
unexport find
 | 
			
		||||
 | 
			
		||||
fontconvert_ttf_lower_files := $(call find, $(asset_fonts_input), *.ttf)
 | 
			
		||||
fontconvert_ttf_upper_files := $(call find, $(asset_fonts_input), *.TTF)
 | 
			
		||||
fontconvert_otf_lower_files := $(call find, $(asset_fonts_input), *.otf)
 | 
			
		||||
fontconvert_otf_upper_files := $(call find, $(asset_fonts_input), *.OTF)
 | 
			
		||||
fontconvert_bdf_lower_files := $(call find, $(asset_fonts_input), *.bdf)
 | 
			
		||||
fontconvert_bdf_upper_files := $(call find, $(asset_fonts_input), *.BDF)
 | 
			
		||||
fontconvert_font_files := $(fontconvert_ttf_lower_files) \
 | 
			
		||||
			  $(fontconvert_ttf_upper_files) \
 | 
			
		||||
			  $(fontconvert_otf_lower_files) \
 | 
			
		||||
			  $(fontconvert_otf_upper_files) \
 | 
			
		||||
			  $(fontconvert_bdf_lower_files) \
 | 
			
		||||
			  $(fontconvert_bdf_upper_files)
 | 
			
		||||
 | 
			
		||||
source_files := $(call find, $(source_paths),*.cpp) $(framework_files) $(ADDITIONAL_SOURCES)
 | 
			
		||||
c_source_files := $(call find, $(source_paths),*.c)
 | 
			
		||||
 | 
			
		||||
object_files := $(source_files:$(touchgfx_path)/%.cpp=$(object_output_path)/touchgfx/%.o) $(c_source_files:$(touchgfx_path)/%.c=$(object_output_path)/touchgfx/%.o)
 | 
			
		||||
object_files := $(object_files:%.cpp=$(object_output_path)/%.o)
 | 
			
		||||
object_files := $(object_files:%.c=$(object_output_path)/%.o)
 | 
			
		||||
dependency_files := $(object_files:%.o=%.d)
 | 
			
		||||
 | 
			
		||||
textconvert_script_path := $(touchgfx_path)/framework/tools/textconvert
 | 
			
		||||
videoconvert_script_path := $(touchgfx_path)/framework/tools/videoconvert
 | 
			
		||||
 | 
			
		||||
text_database := $(asset_texts_input)/texts.xml
 | 
			
		||||
 | 
			
		||||
.PHONY: all clean assets generate_assets build_executable
 | 
			
		||||
 | 
			
		||||
all: generate_assets
 | 
			
		||||
 | 
			
		||||
generate_assets: assets
 | 
			
		||||
	@$(MAKE) -f generated/simulator/gcc/Makefile -r -s $(MFLAGS) build_executable
 | 
			
		||||
 | 
			
		||||
build_executable: $(binary_output_path)/$(simulator_executable) post_build
 | 
			
		||||
 | 
			
		||||
$(binary_output_path)/$(simulator_executable): $(object_files) $(resource_file)
 | 
			
		||||
	@echo Linking $(@)
 | 
			
		||||
	@mkdir -p $(@D)
 | 
			
		||||
	@mkdir -p $(object_output_path)
 | 
			
		||||
	@$(file >$(build_root_path)/objects.tmp) $(foreach F,$(object_files),$(file >>$(build_root_path)/objects.tmp,$F))
 | 
			
		||||
	@$(linker) \
 | 
			
		||||
		$(linker_options) $(linker_options_local) \
 | 
			
		||||
		$(patsubst %,-L%,$(library_path)) \
 | 
			
		||||
		@$(build_root_path)/objects.tmp -o $@ $(resource_file) \
 | 
			
		||||
		$(libstart) $(patsubst %,-l%,$(libraries)) $(libend) $(libextra)
 | 
			
		||||
	@rm -f $(build_root_path)/objects.tmp
 | 
			
		||||
	# Remove old images
 | 
			
		||||
	@rm -f $(binary_output_path)/*.bin
 | 
			
		||||
	@if ls $(asset_videos_output)/bin/*.bin >/dev/null 2>&1; then cp $(asset_videos_output)/bin/*.bin $(binary_output_path); fi
 | 
			
		||||
ifneq ($(UNAME), Linux)
 | 
			
		||||
	@if [ ! -f $(binary_output_path)/SDL2.dll ]; then cp $(sdl_library_path)/SDL2.dll $(binary_output_path); fi
 | 
			
		||||
	@if [ ! -f $(binary_output_path)/SDL2_image.dll ]; then cp $(sdl_library_path)/SDL2_image.dll $(binary_output_path); fi
 | 
			
		||||
	@if [ ! -f $(binary_output_path)/libpng16-16.dll ]; then cp $(sdl_library_path)/libpng16-16.dll $(binary_output_path); fi
 | 
			
		||||
	@if [ ! -f $(binary_output_path)/zlib1.dll ]; then cp $(sdl_library_path)/zlib1.dll $(binary_output_path); fi
 | 
			
		||||
	@if [ ! -f $(binary_output_path)/libjpeg-8.dll ]; then cp $(jpeg_library_path)/libjpeg-8.dll $(binary_output_path); fi
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
.PHONY: post_build
 | 
			
		||||
post_build:
 | 
			
		||||
	@mkdir -p $(binary_output_path)
 | 
			
		||||
	@if [ -f simulator/landscape.png ]; then cp simulator/landscape.png $(binary_output_path); else rm -f $(binary_output_path)/landscape.png; fi
 | 
			
		||||
	@if [ -f simulator/portrait.png ]; then cp simulator/portrait.png $(binary_output_path); else rm -f $(binary_output_path)/portrait.png; fi
 | 
			
		||||
 | 
			
		||||
$(object_output_path)/touchgfx/%.o: $(touchgfx_path)/%.cpp config/gcc/app.mk
 | 
			
		||||
	@echo Compiling $<
 | 
			
		||||
	@mkdir -p $(@D)
 | 
			
		||||
	@$(cpp_compiler) \
 | 
			
		||||
		-MMD -MP $(cpp_compiler_options) $(cpp_compiler_options_local) $(user_cflags) \
 | 
			
		||||
		$(patsubst %,-I%,$(include_paths)) \
 | 
			
		||||
		-c $< -o $@
 | 
			
		||||
 | 
			
		||||
$(object_output_path)/%.o: %.cpp config/gcc/app.mk
 | 
			
		||||
	@echo Compiling $<
 | 
			
		||||
	@mkdir -p $(@D)
 | 
			
		||||
	@$(cpp_compiler) \
 | 
			
		||||
		-MMD -MP $(cpp_compiler_options) $(cpp_compiler_options_local) $(user_cflags) \
 | 
			
		||||
		$(patsubst %,-I%,$(include_paths)) \
 | 
			
		||||
		-c $< -o $@
 | 
			
		||||
 | 
			
		||||
$(object_output_path)/%.o: %.c config/gcc/app.mk
 | 
			
		||||
	@echo Compiling $<
 | 
			
		||||
	@mkdir -p $(@D)
 | 
			
		||||
	@$(c_compiler) \
 | 
			
		||||
		-MMD -MP $(c_compiler_options) $(c_compiler_options_local) $(user_cflags) \
 | 
			
		||||
		$(patsubst %,-I%,$(include_paths)) \
 | 
			
		||||
		-c $< -o $@
 | 
			
		||||
 | 
			
		||||
ifeq ($(MAKECMDGOALS),build_executable)
 | 
			
		||||
$(firstword $(dependency_files)): config/gcc/app.mk
 | 
			
		||||
	@rm -rf $(object_output_path)
 | 
			
		||||
-include $(dependency_files)
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
assets: images texts videos
 | 
			
		||||
 | 
			
		||||
.PHONY: images
 | 
			
		||||
images:
 | 
			
		||||
	@$(imageconvert_executable) -r $(asset_images_input) -w $(asset_images_output)
 | 
			
		||||
 | 
			
		||||
.PHONY: texts
 | 
			
		||||
texts:
 | 
			
		||||
	@ruby $(textconvert_script_path)/main.rb $(text_database) $(fontconvert_executable) $(asset_fonts_output) $(asset_texts_output) $(asset_fonts_input) .
 | 
			
		||||
 | 
			
		||||
.PHONY: videos
 | 
			
		||||
videos:
 | 
			
		||||
	@ruby $(videoconvert_script_path)/videoconvert.rb $(asset_videos_input) $(asset_videos_output)
 | 
			
		||||
 | 
			
		||||
clean:
 | 
			
		||||
	@echo Cleaning
 | 
			
		||||
	@rm -rf $(build_root_path)
 | 
			
		||||
	# Do not remove gui_generated
 | 
			
		||||
	@rm -rf $(asset_images_output)
 | 
			
		||||
	@rm -rf $(asset_fonts_output)
 | 
			
		||||
	@rm -rf $(asset_texts_output)
 | 
			
		||||
	@rm -rf $(asset_videos_output)
 | 
			
		||||
	# Create directory to avoid error if it does not exist
 | 
			
		||||
	@mkdir -p $(asset_root_path)
 | 
			
		||||
	# Remove assets folder if it is empty (i.e. no gui_generated folder)
 | 
			
		||||
	@rmdir --ignore-fail-on-non-empty $(asset_root_path)
 | 
			
		||||
@ -0,0 +1,9 @@
 | 
			
		||||
/*********************************************************************************/
 | 
			
		||||
/********** THIS FILE IS GENERATED BY TOUCHGFX DESIGNER, DO NOT MODIFY ***********/
 | 
			
		||||
/*********************************************************************************/
 | 
			
		||||
#include <touchgfx/hal/HAL.hpp>
 | 
			
		||||
#include <touchgfx/lcd/LCD.hpp>
 | 
			
		||||
 | 
			
		||||
void setupSimulator(int argc, char** argv, touchgfx::HAL& hal);
 | 
			
		||||
 | 
			
		||||
touchgfx::LCD& setupLCD();
 | 
			
		||||
@ -0,0 +1,354 @@
 | 
			
		||||
/*********************************************************************************/
 | 
			
		||||
/********** THIS FILE IS GENERATED BY TOUCHGFX DESIGNER, DO NOT MODIFY ***********/
 | 
			
		||||
/*********************************************************************************/
 | 
			
		||||
#ifndef TOUCHGFX_DIRECTFRAMEBUFFERVIDEOCONTROLLER_HPP
 | 
			
		||||
#define TOUCHGFX_DIRECTFRAMEBUFFERVIDEOCONTROLLER_HPP
 | 
			
		||||
 | 
			
		||||
#include <touchgfx/widgets/VideoWidget.hpp>
 | 
			
		||||
#include <simulator/video/MJPEGDecoder.hpp>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Strategy:
 | 
			
		||||
 * Decode directly into the framebuffer in draw.
 | 
			
		||||
 * Tick will decide if we are going to a new frame.
 | 
			
		||||
 */
 | 
			
		||||
template <uint32_t no_streams, touchgfx::Bitmap::BitmapFormat output_format>
 | 
			
		||||
class DirectFrameBufferVideoController : public touchgfx::VideoController
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    DirectFrameBufferVideoController()
 | 
			
		||||
        : VideoController(), allowSkipFrames(true)
 | 
			
		||||
    {
 | 
			
		||||
        assert((no_streams > 0) && "Video: Number of streams zero!");
 | 
			
		||||
 | 
			
		||||
        // Clear arrays
 | 
			
		||||
        memset(mjpegDecoders, 0, sizeof(mjpegDecoders));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    Handle registerVideoWidget(touchgfx::VideoWidget& widget)
 | 
			
		||||
    {
 | 
			
		||||
        // Find stream handle for Widget
 | 
			
		||||
        Handle handle = getFreeHandle();
 | 
			
		||||
 | 
			
		||||
        streams[handle].isActive = true;
 | 
			
		||||
 | 
			
		||||
        //Set Widget buffer format and address
 | 
			
		||||
        widget.setVideoBufferFormat(output_format, 0, 0);
 | 
			
		||||
        widget.setVideoBuffer((uint8_t*)0);
 | 
			
		||||
 | 
			
		||||
        return handle;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void unregisterVideoWidget(const Handle handle)
 | 
			
		||||
    {
 | 
			
		||||
        streams[handle].isActive = false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void setFrameRate(const Handle handle, uint32_t ui_frames, uint32_t video_frames)
 | 
			
		||||
    {
 | 
			
		||||
        assert(handle < no_streams);
 | 
			
		||||
        Stream& stream = streams[handle];
 | 
			
		||||
 | 
			
		||||
        // Reset counters
 | 
			
		||||
        stream.frameCount = 0;
 | 
			
		||||
        stream.tickCount = 0;
 | 
			
		||||
 | 
			
		||||
        // Save requested frame rate ratio
 | 
			
		||||
        stream.frame_rate_ticks = ui_frames;
 | 
			
		||||
        stream.frame_rate_video = video_frames;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void setVideoData(const Handle handle, const uint8_t* movie, const uint32_t length)
 | 
			
		||||
    {
 | 
			
		||||
        assert(handle < no_streams);
 | 
			
		||||
 | 
			
		||||
        // Reset decoder to first frame
 | 
			
		||||
        mjpegDecoders[handle]->setVideoData(movie, length);
 | 
			
		||||
 | 
			
		||||
        // Lower flag to show the first frame
 | 
			
		||||
        Stream& stream = streams[handle];
 | 
			
		||||
        stream.frameNumber = mjpegDecoders[handle]->getCurrentFrameNumber();
 | 
			
		||||
        stream.doDecodeNextFrame = false;
 | 
			
		||||
 | 
			
		||||
        // Stop playing
 | 
			
		||||
        setCommand(handle, PAUSE, 0);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void setVideoData(const Handle handle, touchgfx::VideoDataReader& reader)
 | 
			
		||||
    {
 | 
			
		||||
        assert(handle < no_streams);
 | 
			
		||||
 | 
			
		||||
        // Reset decoder to first frame
 | 
			
		||||
        mjpegDecoders[handle]->setVideoData(reader);
 | 
			
		||||
 | 
			
		||||
        // Lower flag to show the first frame
 | 
			
		||||
        Stream& stream = streams[handle];
 | 
			
		||||
        stream.frameNumber = mjpegDecoders[handle]->getCurrentFrameNumber();
 | 
			
		||||
        stream.doDecodeNextFrame = false;
 | 
			
		||||
 | 
			
		||||
        // Stop playing
 | 
			
		||||
        setCommand(handle, PAUSE, 0);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void setCommand(const Handle handle, Command cmd, uint32_t param)
 | 
			
		||||
    {
 | 
			
		||||
        assert(handle < no_streams);
 | 
			
		||||
        Stream& stream = streams[handle];
 | 
			
		||||
 | 
			
		||||
        switch (cmd)
 | 
			
		||||
        {
 | 
			
		||||
        case PLAY:
 | 
			
		||||
            // Cannot Play without movie
 | 
			
		||||
            if (mjpegDecoders[handle]->hasVideo())
 | 
			
		||||
            {
 | 
			
		||||
                stream.isPlaying = true;
 | 
			
		||||
                stream.isShowingOneFrame = false;
 | 
			
		||||
                // Reset counters
 | 
			
		||||
                stream.frameCount = 0;
 | 
			
		||||
                stream.tickCount = 0;
 | 
			
		||||
                // If non-repeating video stopped at the end, kick to next frame
 | 
			
		||||
                if (!stream.repeat)
 | 
			
		||||
                {
 | 
			
		||||
                    MJPEGDecoder* const decoder = mjpegDecoders[handle];
 | 
			
		||||
                    if (decoder->getCurrentFrameNumber() == decoder->getNumberOfFrames())
 | 
			
		||||
                    {
 | 
			
		||||
                        decoder->gotoNextFrame();
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            break;
 | 
			
		||||
        case PAUSE:
 | 
			
		||||
            stream.isPlaying = false;
 | 
			
		||||
            stream.isShowingOneFrame = false;
 | 
			
		||||
            break;
 | 
			
		||||
        case SEEK:
 | 
			
		||||
            stream.seek_to_frame = param;
 | 
			
		||||
            // Reset counters
 | 
			
		||||
            stream.frameCount = 0;
 | 
			
		||||
            stream.tickCount = 0;
 | 
			
		||||
            break;
 | 
			
		||||
        case SHOW:
 | 
			
		||||
            stream.seek_to_frame = param;
 | 
			
		||||
            stream.isShowingOneFrame = true;
 | 
			
		||||
            stream.doDecodeNextFrame = true;
 | 
			
		||||
            // Reset counters
 | 
			
		||||
            stream.frameCount = 0;
 | 
			
		||||
            stream.tickCount = 0;
 | 
			
		||||
            break;
 | 
			
		||||
        case STOP:
 | 
			
		||||
            stream.isPlaying = false;
 | 
			
		||||
            stream.isShowingOneFrame = false;
 | 
			
		||||
            stream.seek_to_frame = 1;
 | 
			
		||||
            // Reset counters
 | 
			
		||||
            stream.frameCount = 0;
 | 
			
		||||
            stream.tickCount = 0;
 | 
			
		||||
            break;
 | 
			
		||||
        case SET_REPEAT:
 | 
			
		||||
            stream.repeat = (param > 0);
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool updateFrame(const Handle handle, touchgfx::VideoWidget& widget)
 | 
			
		||||
    {
 | 
			
		||||
        assert(handle < no_streams);
 | 
			
		||||
        Stream& stream = streams[handle];
 | 
			
		||||
 | 
			
		||||
        bool hasMoreFrames = true;
 | 
			
		||||
 | 
			
		||||
        if (stream.isPlaying || stream.isShowingOneFrame)
 | 
			
		||||
        {
 | 
			
		||||
            // Increase tickCount
 | 
			
		||||
            stream.tickCount+=HAL::getInstance()->getLCDRefreshCount();
 | 
			
		||||
 | 
			
		||||
            // Lower flag
 | 
			
		||||
            stream.isShowingOneFrame = false;
 | 
			
		||||
 | 
			
		||||
            if (stream.doDecodeNextFrame)
 | 
			
		||||
            {
 | 
			
		||||
                MJPEGDecoder* const decoder = mjpegDecoders[handle];
 | 
			
		||||
                // Invalidate to get widget redrawn
 | 
			
		||||
                widget.invalidate();
 | 
			
		||||
                // Seek or increment video frame
 | 
			
		||||
                if (stream.seek_to_frame > 0)
 | 
			
		||||
                {
 | 
			
		||||
                    decoder->gotoFrame(stream.seek_to_frame);
 | 
			
		||||
                    hasMoreFrames = (stream.seek_to_frame < decoder->getNumberOfFrames());
 | 
			
		||||
                    stream.seek_to_frame = 0;
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
                    if (stream.skip_frames > 0)
 | 
			
		||||
                    {
 | 
			
		||||
                        decoder->gotoFrame(decoder->getCurrentFrameNumber() + stream.skip_frames);
 | 
			
		||||
                        stream.frameCount += stream.skip_frames;
 | 
			
		||||
                        stream.skip_frames = 0;
 | 
			
		||||
                    }
 | 
			
		||||
                    if (stream.repeat)
 | 
			
		||||
                    {
 | 
			
		||||
                        hasMoreFrames = decoder->gotoNextFrame();
 | 
			
		||||
                    }
 | 
			
		||||
                    else
 | 
			
		||||
                    {
 | 
			
		||||
                        if (decoder->getCurrentFrameNumber() < decoder->getNumberOfFrames())
 | 
			
		||||
                        {
 | 
			
		||||
                            hasMoreFrames = decoder->gotoNextFrame();
 | 
			
		||||
                        }
 | 
			
		||||
                        else
 | 
			
		||||
                        {
 | 
			
		||||
                            stream.isPlaying = false;
 | 
			
		||||
                            hasMoreFrames = false;
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                stream.frameNumber = decoder->getCurrentFrameNumber();
 | 
			
		||||
                stream.frameCount++;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Save decode status for next frame
 | 
			
		||||
            stream.doDecodeNextFrame = decodeForNextTick(stream);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return hasMoreFrames;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void draw(const Handle handle, const touchgfx::Rect& invalidatedArea, const touchgfx::VideoWidget& widget)
 | 
			
		||||
    {
 | 
			
		||||
        assert(handle < no_streams);
 | 
			
		||||
 | 
			
		||||
        if (output_format != Bitmap::RGB565 && output_format != Bitmap::RGB888 && output_format != Bitmap::ARGB8888)
 | 
			
		||||
        {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (mjpegDecoders[handle]->hasVideo())
 | 
			
		||||
        {
 | 
			
		||||
            uint8_t* wbuf = (uint8_t*)touchgfx::HAL::getInstance()->lockFrameBuffer();
 | 
			
		||||
            const touchgfx::Rect& absolute = widget.getAbsoluteRect();
 | 
			
		||||
 | 
			
		||||
            // Get frame buffer pointer to upper left of widget in framebuffer coordinates
 | 
			
		||||
            switch(output_format)
 | 
			
		||||
            {
 | 
			
		||||
                case Bitmap::RGB565:
 | 
			
		||||
                    wbuf += (absolute.x + absolute.y * touchgfx::HAL::FRAME_BUFFER_WIDTH) * 2;
 | 
			
		||||
                    break;
 | 
			
		||||
                case Bitmap::RGB888:
 | 
			
		||||
                    wbuf += (absolute.x + absolute.y * touchgfx::HAL::FRAME_BUFFER_WIDTH) * 3;
 | 
			
		||||
                    break;
 | 
			
		||||
                case Bitmap::ARGB8888:
 | 
			
		||||
                    wbuf += (absolute.x + absolute.y * touchgfx::HAL::FRAME_BUFFER_WIDTH) * 4;
 | 
			
		||||
                    break;
 | 
			
		||||
                default:
 | 
			
		||||
                    break;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Decode relevant part of the frame to the framebuffer
 | 
			
		||||
            mjpegDecoders[handle]->decodeFrame(invalidatedArea, wbuf, touchgfx::HAL::FRAME_BUFFER_WIDTH);
 | 
			
		||||
            // Release frame buffer
 | 
			
		||||
            touchgfx::HAL::getInstance()->unlockFrameBuffer();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void addDecoder(MJPEGDecoder& decoder, uint32_t index)
 | 
			
		||||
    {
 | 
			
		||||
        assert(index < no_streams);
 | 
			
		||||
        mjpegDecoders[index] = &decoder;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    uint32_t getCurrentFrameNumber(const Handle handle)
 | 
			
		||||
    {
 | 
			
		||||
        assert(handle < no_streams);
 | 
			
		||||
        Stream& stream = streams[handle];
 | 
			
		||||
 | 
			
		||||
        return stream.frameNumber;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void getVideoInformation(const Handle handle, touchgfx::VideoInformation* data)
 | 
			
		||||
    {
 | 
			
		||||
        assert(handle < no_streams);
 | 
			
		||||
        mjpegDecoders[handle]->getVideoInfo(data);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool getIsPlaying(const Handle handle)
 | 
			
		||||
    {
 | 
			
		||||
        assert(handle < no_streams);
 | 
			
		||||
        Stream& stream = streams[handle];
 | 
			
		||||
        return stream.isPlaying;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void setFrameRateCompensation(const bool allow)
 | 
			
		||||
    {
 | 
			
		||||
        allowSkipFrames = allow;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    class Stream
 | 
			
		||||
    {
 | 
			
		||||
    public:
 | 
			
		||||
        Stream()
 | 
			
		||||
            : frameCount(0), frameNumber(0), tickCount(0),
 | 
			
		||||
              frame_rate_video(0), frame_rate_ticks(0),
 | 
			
		||||
              seek_to_frame(0),
 | 
			
		||||
              isActive(false), isPlaying(false), isShowingOneFrame(false), repeat(true),
 | 
			
		||||
              doDecodeNextFrame(false)
 | 
			
		||||
        {
 | 
			
		||||
        }
 | 
			
		||||
        uint32_t frameCount;       // Video frames decoded since play
 | 
			
		||||
        uint32_t frameNumber;      // Video frame showed number
 | 
			
		||||
        uint32_t tickCount;        // UI frames since play
 | 
			
		||||
        uint32_t frame_rate_video; // Ratio of frames wanted counter
 | 
			
		||||
        uint32_t frame_rate_ticks; // Ratio of frames wanted divider
 | 
			
		||||
        uint32_t seek_to_frame;    // Requested next frame number
 | 
			
		||||
        uint32_t skip_frames;      // Number of frames to skip to keep frame rate
 | 
			
		||||
        bool isActive;
 | 
			
		||||
        bool isPlaying;
 | 
			
		||||
        bool isShowingOneFrame;
 | 
			
		||||
        bool repeat;
 | 
			
		||||
        bool doDecodeNextFrame; // High if we should go to next frame in next tick
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    MJPEGDecoder* mjpegDecoders[no_streams];
 | 
			
		||||
    Stream streams[no_streams];
 | 
			
		||||
    bool allowSkipFrames;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Return true, if new video frame should be decoded for the next tick (keep video decode framerate low)
 | 
			
		||||
     */
 | 
			
		||||
    bool decodeForNextTick(Stream& stream)
 | 
			
		||||
    {
 | 
			
		||||
        // Running in UI thread
 | 
			
		||||
 | 
			
		||||
        // Compare tickCount/frameNumber to frame_rate_ticks/frame_rate_video
 | 
			
		||||
        if ((stream.tickCount * stream.frame_rate_video) > (stream.frame_rate_ticks * stream.frameCount))
 | 
			
		||||
        {
 | 
			
		||||
            if (allowSkipFrames)
 | 
			
		||||
            {
 | 
			
		||||
                stream.skip_frames = (stream.tickCount * stream.frame_rate_video - stream.frame_rate_ticks * stream.frameCount) / stream.frame_rate_ticks;
 | 
			
		||||
                if (stream.skip_frames > 0)
 | 
			
		||||
                {
 | 
			
		||||
                    stream.skip_frames--;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    Handle getFreeHandle()
 | 
			
		||||
    {
 | 
			
		||||
        for (uint32_t i = 0; i < no_streams; i++)
 | 
			
		||||
        {
 | 
			
		||||
            if (streams[i].isActive == false)
 | 
			
		||||
            {
 | 
			
		||||
                return static_cast<VideoController::Handle>(i);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        assert(0 && "Unable to find free video stream handle!");
 | 
			
		||||
        return static_cast<VideoController::Handle>(0);
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif // TOUCHGFX_DIRECTFRAMEBUFFERVIDEOCONTROLLER_HPP
 | 
			
		||||
@ -0,0 +1,75 @@
 | 
			
		||||
/*********************************************************************************/
 | 
			
		||||
/********** THIS FILE IS GENERATED BY TOUCHGFX DESIGNER, DO NOT MODIFY ***********/
 | 
			
		||||
/*********************************************************************************/
 | 
			
		||||
#ifndef TOUCHGFX_MJPEGDECODER_HPP
 | 
			
		||||
#define TOUCHGFX_MJPEGDECODER_HPP
 | 
			
		||||
 | 
			
		||||
#include <touchgfx/hal/Types.hpp>
 | 
			
		||||
#include <touchgfx/hal/VideoController.hpp>
 | 
			
		||||
 | 
			
		||||
class MJPEGDecoder
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    virtual ~MJPEGDecoder()
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    //Set video data for the decoder
 | 
			
		||||
    virtual void setVideoData(const uint8_t* movie, const uint32_t length) = 0;
 | 
			
		||||
 | 
			
		||||
    //Set video data for the decoder
 | 
			
		||||
    virtual void setVideoData(touchgfx::VideoDataReader& reader) = 0;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Check if MJPEGDecoder has a video.
 | 
			
		||||
     *
 | 
			
		||||
     * @return Returns true if the MJPEGDecoder has a video.
 | 
			
		||||
     */
 | 
			
		||||
    virtual bool hasVideo() = 0;
 | 
			
		||||
 | 
			
		||||
    //Increment position to next frame and decode and convert to RGB
 | 
			
		||||
    virtual bool decodeNextFrame(uint8_t* buffer, uint16_t width, uint16_t height, uint32_t stride) = 0;
 | 
			
		||||
 | 
			
		||||
    //Increment position to next frame and decode. Used with decodeFrame.
 | 
			
		||||
    virtual bool gotoNextFrame() = 0;
 | 
			
		||||
 | 
			
		||||
    //Decode part of the current frame, framebuffer is locked, area is drawn relative to frameBuffer
 | 
			
		||||
    virtual bool decodeFrame(const touchgfx::Rect& area, uint8_t* frameBuffer, uint32_t framebufferStride) = 0;
 | 
			
		||||
 | 
			
		||||
    //Decode thumbnail, assumes buffer stride is width
 | 
			
		||||
    virtual bool decodeThumbnail(uint32_t frameno, uint8_t* buffer, uint16_t width, uint16_t height) = 0;
 | 
			
		||||
 | 
			
		||||
    //Set current frame number
 | 
			
		||||
    virtual void gotoFrame(uint32_t frameno) = 0;
 | 
			
		||||
 | 
			
		||||
    //Get current frame number
 | 
			
		||||
    virtual uint32_t getCurrentFrameNumber() const = 0;
 | 
			
		||||
 | 
			
		||||
    //Get number of frames in video
 | 
			
		||||
    virtual uint32_t getNumberOfFrames() = 0;
 | 
			
		||||
 | 
			
		||||
    //Read video information
 | 
			
		||||
    virtual void getVideoInfo(touchgfx::VideoInformation* data) = 0;
 | 
			
		||||
 | 
			
		||||
    enum AVIErrors
 | 
			
		||||
    {
 | 
			
		||||
        AVI_NO_ERROR,
 | 
			
		||||
        AVI_NO_BUFFERS,
 | 
			
		||||
        AVI_NO_FILE,
 | 
			
		||||
        AVI_ERROR_NOT_RIFF,
 | 
			
		||||
        AVI_ERROR_AVI_HEADER_NOT_FOUND,
 | 
			
		||||
        AVI_ERROR_AVI_LIST_NOT_FOUND,
 | 
			
		||||
        AVI_ERROR_AVI_HDRL_NOT_FOUND,
 | 
			
		||||
        AVI_ERROR_AVI_AVIH_NOT_FOUND,
 | 
			
		||||
        AVI_ERROR_AVI_HEADER_TO_SHORT, //not full header provided
 | 
			
		||||
        AVI_ERROR_FILE_BUFFER_TO_SMALL,
 | 
			
		||||
        AVI_ERROR_MOVI_NOT_FOUND,
 | 
			
		||||
        AVI_ERROR_IDX1_NOT_FOUND,
 | 
			
		||||
        AVI_ERROR_FRAMENO_TO_HIGH,
 | 
			
		||||
        AVI_ERROR_EOF_REACHED
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    AVIErrors virtual getLastError() = 0;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif // TOUCHGFX_MJPEGDECODER_HPP
 | 
			
		||||
@ -0,0 +1,73 @@
 | 
			
		||||
/*********************************************************************************/
 | 
			
		||||
/********** THIS FILE IS GENERATED BY TOUCHGFX DESIGNER, DO NOT MODIFY ***********/
 | 
			
		||||
/*********************************************************************************/
 | 
			
		||||
#ifndef TOUCHGFX_SOFTWAREMJPEGDECODER_HPP
 | 
			
		||||
#define TOUCHGFX_SOFTWAREMJPEGDECODER_HPP
 | 
			
		||||
 | 
			
		||||
#include <simulator/video/MJPEGDecoder.hpp>
 | 
			
		||||
 | 
			
		||||
class SoftwareMJPEGDecoder : public MJPEGDecoder
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    SoftwareMJPEGDecoder(uint8_t* linebuffer);
 | 
			
		||||
 | 
			
		||||
    virtual void setVideoData(const uint8_t* movie, const uint32_t length);
 | 
			
		||||
 | 
			
		||||
    virtual void setVideoData(touchgfx::VideoDataReader& reader);
 | 
			
		||||
 | 
			
		||||
    virtual bool hasVideo();
 | 
			
		||||
 | 
			
		||||
    virtual bool decodeNextFrame(uint8_t* frameBuffer, uint16_t width, uint16_t height, uint32_t framebuffer_width);
 | 
			
		||||
 | 
			
		||||
    virtual bool gotoNextFrame();
 | 
			
		||||
 | 
			
		||||
    virtual bool decodeFrame(const touchgfx::Rect& area, uint8_t* frameBuffer, uint32_t framebuffer_width);
 | 
			
		||||
 | 
			
		||||
    virtual bool decodeThumbnail(uint32_t frameno, uint8_t* buffer, uint16_t width, uint16_t height);
 | 
			
		||||
 | 
			
		||||
    virtual void gotoFrame(uint32_t frameno);
 | 
			
		||||
 | 
			
		||||
    virtual uint32_t getCurrentFrameNumber() const
 | 
			
		||||
    {
 | 
			
		||||
        return frameNumber;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    virtual uint32_t getNumberOfFrames();
 | 
			
		||||
 | 
			
		||||
    virtual void getVideoInfo(touchgfx::VideoInformation* data);
 | 
			
		||||
 | 
			
		||||
    void setAVIFileBuffer(uint8_t* buffer, uint32_t size)
 | 
			
		||||
    {
 | 
			
		||||
        aviBuffer = buffer, aviBufferLength = size;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    AVIErrors getLastError()
 | 
			
		||||
    {
 | 
			
		||||
        return lastError;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    void readVideoHeader();
 | 
			
		||||
    void decodeMJPEGFrame(const uint8_t* const mjpgdata, const uint32_t length, uint8_t* buffer, uint16_t width, uint16_t height, uint32_t stride);
 | 
			
		||||
    int compare(const uint32_t offset, const char* str, uint32_t num);
 | 
			
		||||
    uint32_t getU32(const uint32_t offset);
 | 
			
		||||
    uint32_t getU16(const uint32_t offset);
 | 
			
		||||
    const uint8_t* readData(uint32_t offset, uint32_t length);
 | 
			
		||||
 | 
			
		||||
    touchgfx::VideoInformation videoInfo;
 | 
			
		||||
    uint32_t frameNumber;
 | 
			
		||||
    uint32_t currentMovieOffset;
 | 
			
		||||
    uint32_t indexOffset;
 | 
			
		||||
    uint32_t firstFrameOffset;
 | 
			
		||||
    uint32_t lastFrameEnd;
 | 
			
		||||
    uint32_t movieLength;
 | 
			
		||||
    const uint8_t* movieData;
 | 
			
		||||
    touchgfx::VideoDataReader* reader;
 | 
			
		||||
    uint8_t* lineBuffer;
 | 
			
		||||
    uint8_t* aviBuffer;
 | 
			
		||||
    uint32_t aviBufferLength;
 | 
			
		||||
    uint32_t aviBufferStartOffset;
 | 
			
		||||
    AVIErrors lastError;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif // TOUCHGFX_SOFTWAREMJPEGDECODER_HPP
 | 
			
		||||
							
								
								
									
										31
									
								
								TouchGFX/generated/simulator/msvs/touchgfx.props
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								TouchGFX/generated/simulator/msvs/touchgfx.props
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,31 @@
 | 
			
		||||
<?xml version="1.0" encoding="utf-8"?>
 | 
			
		||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
 | 
			
		||||
  <ImportGroup Label="PropertySheets" />
 | 
			
		||||
  <PropertyGroup Label="UserMacros" />
 | 
			
		||||
  <PropertyGroup>
 | 
			
		||||
    <DisableFastUpToDateCheck>true</DisableFastUpToDateCheck>
 | 
			
		||||
  </PropertyGroup>
 | 
			
		||||
  <PropertyGroup>
 | 
			
		||||
    <LocalDebuggerEnvironment>PATH=$(TouchGFXReleasePath)\lib\sdl\win32</LocalDebuggerEnvironment>
 | 
			
		||||
  </PropertyGroup>
 | 
			
		||||
  <ItemDefinitionGroup>
 | 
			
		||||
    <ClCompile>
 | 
			
		||||
      <AdditionalIncludeDirectories>$(ApplicationRoot)\gui\include;$(ApplicationRoot)\generated\images\include;$(ApplicationRoot)\generated\bitmaps\include;$(ApplicationRoot)\generated\fonts\include;$(ApplicationRoot)\generated\texts\include;$(ApplicationRoot)\generated\videos\include;$(ApplicationRoot)\generated\gui_generated\include;$(ApplicationRoot)\generated\simulator\include;$(TouchGFXReleasePath)\framework\common\include;$(TouchGFXReleasePath)\framework\mvp\include;$(TouchGFXReleasePath)\framework\include\platform\hal\simulator\sdl\vendor\win32;$(TouchGFXReleasePath)\framework\platform\hal\simulator\sdl\3rdparty\sdl\include\win32;$(TouchGFXReleasePath)\3rdparty\libjpeg\include;$(TouchGFXReleasePath)\framework\include</AdditionalIncludeDirectories>
 | 
			
		||||
      <AdditionalOptions>$(UseBPPOption)</AdditionalOptions>
 | 
			
		||||
      <PreprocessorDefinitions>SIMULATOR;_ITERATOR_DEBUG_LEVEL=0</PreprocessorDefinitions>
 | 
			
		||||
      <DisableSpecificWarnings>4355</DisableSpecificWarnings>
 | 
			
		||||
    </ClCompile>
 | 
			
		||||
  </ItemDefinitionGroup>
 | 
			
		||||
  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
 | 
			
		||||
    <Link>
 | 
			
		||||
      <AdditionalDependencies>$(TouchGFXReleasePath)\lib\sdl\win32\SDL.lib;$(TouchGFXReleasePath)\lib\sdl\win32\SDLmain.lib;$(TouchGFXReleasePath)\lib\sdl\win32\SDL_image.lib;$(TouchGFXReleasePath)\3rdparty\libjpeg\lib\win32\libjpeg-8.lib;$(TouchGFXReleasePath)\lib\win\msvs\libtouchgfx_$(PlatformToolset)_debug.lib;user32.lib;shell32.lib</AdditionalDependencies>
 | 
			
		||||
      <AdditionalOptions>/NODEFAULTLIB:msvcrt.lib</AdditionalOptions>
 | 
			
		||||
    </Link>
 | 
			
		||||
  </ItemDefinitionGroup>
 | 
			
		||||
  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
 | 
			
		||||
    <Link>
 | 
			
		||||
      <AdditionalDependencies>$(TouchGFXReleasePath)\lib\sdl\win32\SDL.lib;$(TouchGFXReleasePath)\lib\sdl\win32\SDLmain.lib;$(TouchGFXReleasePath)\lib\sdl\win32\SDL_image.lib;$(TouchGFXReleasePath)\lib\win\msvs\libtouchgfx_$(PlatformToolset).lib;user32.lib;shell32.lib</AdditionalDependencies>
 | 
			
		||||
    </Link>
 | 
			
		||||
  </ItemDefinitionGroup>
 | 
			
		||||
  <ItemGroup />
 | 
			
		||||
</Project>
 | 
			
		||||
							
								
								
									
										86
									
								
								TouchGFX/generated/simulator/msvs/touchgfx_prebuild.targets
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										86
									
								
								TouchGFX/generated/simulator/msvs/touchgfx_prebuild.targets
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,86 @@
 | 
			
		||||
<?xml version="1.0" encoding="utf-8"?>
 | 
			
		||||
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
 | 
			
		||||
  <ItemGroup>
 | 
			
		||||
    <AllGeneratedFolders Include="$(ApplicationRoot)\generated\fonts;$(ApplicationRoot)\generated\images;$(ApplicationRoot)\generated\texts;$(ApplicationRoot)\generated\videos" />
 | 
			
		||||
  </ItemGroup>
 | 
			
		||||
 | 
			
		||||
  <ItemGroup>
 | 
			
		||||
    <ImageConvertExecutable Include="$(TouchGFXReleasePath)\framework\tools\imageconvert\build\msvs\ImageConvert.exe" />
 | 
			
		||||
  </ItemGroup>
 | 
			
		||||
 | 
			
		||||
  <PropertyGroup>
 | 
			
		||||
    <UseBPPOption>/DUSE_BPP=$(UseBPP)</UseBPPOption>
 | 
			
		||||
  </PropertyGroup>
 | 
			
		||||
 | 
			
		||||
  <PropertyGroup Condition="'$(LCD)'!=''">
 | 
			
		||||
    <LCDOption>/D$(LCD)</LCDOption>
 | 
			
		||||
  </PropertyGroup>
 | 
			
		||||
  <PropertyGroup Condition="'$(LCD)'==''">
 | 
			
		||||
    <LCDOption/>
 | 
			
		||||
  </PropertyGroup>
 | 
			
		||||
 | 
			
		||||
  <PropertyGroup>
 | 
			
		||||
    <touchgfx_env Condition="'$(TouchGFXEnvPath)'==''">$(TouchGFXReleasePath)\..\env</touchgfx_env>
 | 
			
		||||
    <touchgfx_env Condition="'$(TouchGFXEnvPath)'!=''">$(TouchGFXEnvPath)</touchgfx_env>
 | 
			
		||||
  </PropertyGroup>
 | 
			
		||||
 | 
			
		||||
  <Target Name="GenerateBitmapDatabaseFiles" BeforeTargets="ClCompile">
 | 
			
		||||
    <Message Text="Converting images" />
 | 
			
		||||
    <Exec Command="echo Converting images" />
 | 
			
		||||
    <Exec Command=""%(ImageConvertExecutable.FullPath)" -r assets\images -w generated\images" WorkingDirectory="$(ApplicationRoot)" />
 | 
			
		||||
  </Target>
 | 
			
		||||
 | 
			
		||||
  <Target Name="GenerateTextsAndFontsFiles" BeforeTargets="ClCompile">
 | 
			
		||||
    <Message Text="Converting texts and fonts" />
 | 
			
		||||
    <Exec Command="echo Converting texts and fonts" />
 | 
			
		||||
    <Exec Command=""$(touchgfx_env)\MinGW\msys\1.0\Ruby30-x64\bin\ruby.exe" "$(TouchGFXReleasePath)\framework\tools\textconvert\main.rb" "$(ApplicationRoot)\assets\texts\texts.xml" "$(TouchGFXReleasePath)\framework\tools\fontconvert\build\win\fontconvert.out" "$(ApplicationRoot)\generated\fonts" "$(ApplicationRoot)\generated\texts" "$(ApplicationRoot)\assets\fonts" "$(ApplicationRoot)"" />
 | 
			
		||||
  </Target>
 | 
			
		||||
 | 
			
		||||
  <Target Name="GenerateVideos" BeforeTargets="ClCompile">
 | 
			
		||||
    <Message Text="Converting videos" />
 | 
			
		||||
    <Exec Command="echo Converting videos" />
 | 
			
		||||
    <Exec Command=""$(touchgfx_env)\MinGW\msys\1.0\Ruby30-x64\bin\ruby.exe" "$(TouchGFXReleasePath)\framework\tools\videoconvert\videoconvert.rb" "$(ApplicationRoot)" assets\videos generated\videos" />
 | 
			
		||||
  </Target>
 | 
			
		||||
 | 
			
		||||
  <Target Name="CompileAllGeneratedFiles" BeforeTargets="ClCompile">
 | 
			
		||||
    <ItemGroup>
 | 
			
		||||
      <AllGeneratedCompileFiles Include="$(ApplicationRoot)\generated\fonts\**\*.cpp;$(ApplicationRoot)\generated\images\**\*.cpp;$(ApplicationRoot)\generated\texts\**\*.cpp;$(ApplicationRoot)\generated\videos\**\*.cpp" />
 | 
			
		||||
    </ItemGroup>
 | 
			
		||||
    <Message Text="Creating compile items for all generated source files: @(AllGeneratedCompileFiles)" />
 | 
			
		||||
    <Exec Command="echo Creating compile items for all generated source files: @(AllGeneratedCompileFiles)" />
 | 
			
		||||
    <CreateItem Include="@(AllGeneratedCompileFiles)">
 | 
			
		||||
      <Output TaskParameter="Include" ItemName="ClCompile" />
 | 
			
		||||
    </CreateItem>
 | 
			
		||||
  </Target>
 | 
			
		||||
 | 
			
		||||
  <Target Name="CleanupGeneratedFiles" AfterTargets="Clean">
 | 
			
		||||
    <Message Text="Clean-up generated files: @(AllGeneratedFolders)" />
 | 
			
		||||
    <Exec Command="echo Clean-up generated files: @(AllGeneratedFolders)" />
 | 
			
		||||
    <RemoveDir Directories="@(AllGeneratedFolders)" />
 | 
			
		||||
    <ItemGroup>
 | 
			
		||||
      <PostBuildFiles Include="$(OutDir)\*.dll" />
 | 
			
		||||
      <PostBuildFiles Include="$(OutDir)\*.bin" />
 | 
			
		||||
      <PostBuildFiles Include="$(OutDir)\*.png" />
 | 
			
		||||
    </ItemGroup>
 | 
			
		||||
    <Delete Files="@(PostBuildFiles)" />
 | 
			
		||||
  </Target>
 | 
			
		||||
 | 
			
		||||
  <Target Name="PostBuild" AfterTargets="ClCompile">
 | 
			
		||||
    <ItemGroup>
 | 
			
		||||
      <OldVideoFiles Include="$(OutDir)\*.bin" />
 | 
			
		||||
      <NewFiles Include="$(ApplicationRoot)\generated\videos\bin\*.bin" />
 | 
			
		||||
      <NewFiles Include="$(TouchGFXReleasePath)\lib\sdl2\win32\SDL2.dll" />
 | 
			
		||||
      <NewFiles Include="$(TouchGFXReleasePath)\lib\sdl2\win32\SDL2_image.dll" />
 | 
			
		||||
      <NewFiles Include="$(TouchGFXReleasePath)\lib\sdl2\win32\libpng16-16.dll" />
 | 
			
		||||
      <NewFiles Include="$(TouchGFXReleasePath)\lib\sdl2\win32\zlib1.dll" />
 | 
			
		||||
      <NewFiles Include="$(TouchGFXReleasePath)\3rdparty\libjpeg\lib\win32\libjpeg-8.dll" />
 | 
			
		||||
      <NewFiles Include="$(ApplicationRoot)\simulator\landscape.png" />
 | 
			
		||||
      <NewFiles Include="$(ApplicationRoot)\simulator\portrait.png" />
 | 
			
		||||
    </ItemGroup>
 | 
			
		||||
    <Delete Files="@(OldVideoFiles)" />
 | 
			
		||||
    <Copy SourceFiles="@(NewFiles)"
 | 
			
		||||
          DestinationFolder="$(OutDir)"
 | 
			
		||||
          SkipUnchangedFiles="true"
 | 
			
		||||
          Condition="Exists('%(FullPath)')" />
 | 
			
		||||
  </Target>
 | 
			
		||||
</Project>
 | 
			
		||||
							
								
								
									
										29
									
								
								TouchGFX/generated/simulator/msvs/touchgfx_sdl2.props
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								TouchGFX/generated/simulator/msvs/touchgfx_sdl2.props
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,29 @@
 | 
			
		||||
<?xml version="1.0" encoding="utf-8"?>
 | 
			
		||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
 | 
			
		||||
  <ImportGroup Label="PropertySheets" />
 | 
			
		||||
  <PropertyGroup Label="UserMacros" />
 | 
			
		||||
  <PropertyGroup>
 | 
			
		||||
    <DisableFastUpToDateCheck>true</DisableFastUpToDateCheck>
 | 
			
		||||
  </PropertyGroup>
 | 
			
		||||
  <PropertyGroup>
 | 
			
		||||
    <LocalDebuggerEnvironment>PATH=$(TouchGFXReleasePath)\lib\sdl2\win32</LocalDebuggerEnvironment>
 | 
			
		||||
  </PropertyGroup>
 | 
			
		||||
  <ItemDefinitionGroup>
 | 
			
		||||
    <ClCompile>
 | 
			
		||||
      <AdditionalIncludeDirectories>$(ApplicationRoot)\gui\include;$(ApplicationRoot)\generated\images\include;$(ApplicationRoot)\generated\bitmaps\include;$(ApplicationRoot)\generated\fonts\include;$(ApplicationRoot)\generated\texts\include;$(ApplicationRoot)\generated\videos\include;$(ApplicationRoot)\generated\gui_generated\include;$(ApplicationRoot)\generated\simulator\include;$(TouchGFXReleasePath)\framework\common\include;$(TouchGFXReleasePath)\framework\mvp\include;$(TouchGFXReleasePath)\framework\include\platform\hal\simulator\sdl2\vendor;$(TouchGFXReleasePath)\3rdparty\libjpeg\include;$(TouchGFXReleasePath)\framework\include</AdditionalIncludeDirectories>
 | 
			
		||||
      <AdditionalOptions>$(UseBPPOption)</AdditionalOptions>
 | 
			
		||||
      <PreprocessorDefinitions>SIMULATOR;_ITERATOR_DEBUG_LEVEL=0</PreprocessorDefinitions>
 | 
			
		||||
      <DisableSpecificWarnings>4355</DisableSpecificWarnings>
 | 
			
		||||
    </ClCompile>
 | 
			
		||||
  </ItemDefinitionGroup>
 | 
			
		||||
  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
 | 
			
		||||
    <Link>
 | 
			
		||||
      <AdditionalDependencies>$(TouchGFXReleasePath)\lib\sdl2\win32\SDL2.lib;$(TouchGFXReleasePath)\lib\sdl2\win32\SDL2_image.lib;$(TouchGFXReleasePath)\3rdparty\libjpeg\lib\win32\libjpeg-8.lib;$(TouchGFXReleasePath)\lib\win\msvs\libtouchgfx_$(PlatformToolset)_debug.lib;user32.lib;shell32.lib</AdditionalDependencies>      <AdditionalOptions>/NODEFAULTLIB:msvcrt.lib</AdditionalOptions>
 | 
			
		||||
    </Link>
 | 
			
		||||
  </ItemDefinitionGroup>
 | 
			
		||||
  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
 | 
			
		||||
    <Link>
 | 
			
		||||
      <AdditionalDependencies>$(TouchGFXReleasePath)\lib\sdl2\win32\SDL2.lib;$(TouchGFXReleasePath)\lib\sdl2\win32\SDL2_image.lib;$(TouchGFXReleasePath)\3rdparty\libjpeg\lib\win32\libjpeg-8.lib;$(TouchGFXReleasePath)\lib\win\msvs\libtouchgfx_$(PlatformToolset).lib;user32.lib;shell32.lib</AdditionalDependencies>    </Link>
 | 
			
		||||
  </ItemDefinitionGroup>
 | 
			
		||||
  <ItemGroup />
 | 
			
		||||
</Project>
 | 
			
		||||
							
								
								
									
										29
									
								
								TouchGFX/generated/simulator/src/mainBase.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								TouchGFX/generated/simulator/src/mainBase.cpp
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,29 @@
 | 
			
		||||
/*********************************************************************************/
 | 
			
		||||
/********** THIS FILE IS GENERATED BY TOUCHGFX DESIGNER, DO NOT MODIFY ***********/
 | 
			
		||||
/*********************************************************************************/
 | 
			
		||||
#include <simulator/mainBase.hpp>
 | 
			
		||||
#include <platform/hal/simulator/sdl2/HALSDL2.hpp>
 | 
			
		||||
#include <common/TouchGFXInit.hpp>
 | 
			
		||||
#include <platform/driver/lcd/LCD16bpp.hpp>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
#ifdef __GNUC__
 | 
			
		||||
#define fopen_s(pFile, filename, mode) (((*(pFile)) = fopen((filename), (mode))) == NULL)
 | 
			
		||||
#endif
 | 
			
		||||
touchgfx::LCD16bpp lcd;
 | 
			
		||||
 | 
			
		||||
void setupSimulator(int argc, char** argv, touchgfx::HAL& hal)
 | 
			
		||||
{
 | 
			
		||||
    // Simulate hardware running at 60Hz generating a vsync every 16.6667 ms
 | 
			
		||||
    static_cast<touchgfx::HALSDL2&>(hal).setVsyncInterval(16.6667f);
 | 
			
		||||
    static_cast<touchgfx::HALSDL2&>(hal).setWindowTitle("MyApplication");
 | 
			
		||||
 | 
			
		||||
    // Initialize SDL
 | 
			
		||||
    bool sdl_init_result = static_cast<touchgfx::HALSDL2&>(hal).sdl_init(argc, argv);
 | 
			
		||||
    assert(sdl_init_result && "Error during SDL initialization");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
touchgfx::LCD& setupLCD()
 | 
			
		||||
{
 | 
			
		||||
    return lcd;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										548
									
								
								TouchGFX/generated/simulator/src/video/SoftwareMJPEGDecoder.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										548
									
								
								TouchGFX/generated/simulator/src/video/SoftwareMJPEGDecoder.cpp
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,548 @@
 | 
			
		||||
/*********************************************************************************/
 | 
			
		||||
/********** THIS FILE IS GENERATED BY TOUCHGFX DESIGNER, DO NOT MODIFY ***********/
 | 
			
		||||
/*********************************************************************************/
 | 
			
		||||
#include <jinclude.h>
 | 
			
		||||
#include <jpeglib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <simulator/video/SoftwareMJPEGDecoder.hpp>
 | 
			
		||||
 | 
			
		||||
#define VIDEO_DECODE_FORMAT 16
 | 
			
		||||
 | 
			
		||||
namespace
 | 
			
		||||
{
 | 
			
		||||
struct JPEG_RGB
 | 
			
		||||
{
 | 
			
		||||
    uint8_t B;
 | 
			
		||||
    uint8_t G;
 | 
			
		||||
    uint8_t R;
 | 
			
		||||
#if VIDEO_DECODE_FORMAT == 32
 | 
			
		||||
    uint8_t X;
 | 
			
		||||
#endif
 | 
			
		||||
};
 | 
			
		||||
} // namespace
 | 
			
		||||
 | 
			
		||||
SoftwareMJPEGDecoder::SoftwareMJPEGDecoder(uint8_t* buffer)
 | 
			
		||||
    : frameNumber(0), currentMovieOffset(0), indexOffset(0), firstFrameOffset(0), lastFrameEnd(0), movieLength(0), movieData(0),
 | 
			
		||||
      reader(0), lineBuffer(buffer), aviBuffer(0), aviBufferLength(0), aviBufferStartOffset(0), lastError(AVI_NO_ERROR)
 | 
			
		||||
{
 | 
			
		||||
    //clear video info
 | 
			
		||||
    videoInfo.ms_between_frames = 0;
 | 
			
		||||
    videoInfo.number_of_frames = 0;
 | 
			
		||||
    videoInfo.frame_width = 0;
 | 
			
		||||
    videoInfo.frame_height = 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int SoftwareMJPEGDecoder::compare(const uint32_t offset, const char* str, uint32_t num)
 | 
			
		||||
{
 | 
			
		||||
    const char* src;
 | 
			
		||||
    if (reader != 0)
 | 
			
		||||
    {
 | 
			
		||||
        // Assuming data is in buffer!
 | 
			
		||||
        src = reinterpret_cast<const char*>(aviBuffer + (offset - aviBufferStartOffset));
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        src = (const char*)movieData + offset;
 | 
			
		||||
    }
 | 
			
		||||
    return strncmp(src, str, num);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline uint32_t SoftwareMJPEGDecoder::getU32(const uint32_t offset)
 | 
			
		||||
{
 | 
			
		||||
    if (reader != 0)
 | 
			
		||||
    {
 | 
			
		||||
        // Assuming data is in buffer!
 | 
			
		||||
        const uint32_t index = offset - aviBufferStartOffset;
 | 
			
		||||
        return aviBuffer[index + 0] | (aviBuffer[index + 1] << 8) | (aviBuffer[index + 2] << 16) | (aviBuffer[index + 3] << 24);
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        const uint8_t* const d = movieData + offset;
 | 
			
		||||
        return d[0] | (d[1] << 8) | (d[2] << 16) | (d[3] << 24);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
inline uint32_t SoftwareMJPEGDecoder::getU16(const uint32_t offset)
 | 
			
		||||
{
 | 
			
		||||
    if (reader != 0)
 | 
			
		||||
    {
 | 
			
		||||
        // Assuming data is in buffer!
 | 
			
		||||
        const uint32_t index = offset - aviBufferStartOffset;
 | 
			
		||||
        return aviBuffer[index + 0] | (aviBuffer[index + 1] << 8);
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        const uint8_t* const d = movieData + offset;
 | 
			
		||||
        return d[0] | (d[1] << 8);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const uint8_t* SoftwareMJPEGDecoder::readData(uint32_t offset, uint32_t length)
 | 
			
		||||
{
 | 
			
		||||
    if (reader != 0)
 | 
			
		||||
    {
 | 
			
		||||
        if (length > aviBufferLength)
 | 
			
		||||
        {
 | 
			
		||||
            lastError = AVI_ERROR_FILE_BUFFER_TO_SMALL;
 | 
			
		||||
            assert(!"Buffer to small");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        reader->seek(offset);
 | 
			
		||||
        if (!reader->readData(aviBuffer, length))
 | 
			
		||||
        {
 | 
			
		||||
            lastError = AVI_ERROR_EOF_REACHED;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        aviBufferStartOffset = offset;
 | 
			
		||||
        return aviBuffer;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return movieData + offset;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool SoftwareMJPEGDecoder::decodeNextFrame(uint8_t* buffer, uint16_t buffer_width, uint16_t buffer_height, uint32_t buffer_stride)
 | 
			
		||||
{
 | 
			
		||||
    assert((frameNumber > 0) && "SoftwareMJPEGDecoder decoding without frame data!");
 | 
			
		||||
 | 
			
		||||
    //find next frame and decode it
 | 
			
		||||
    readData(currentMovieOffset, 8);
 | 
			
		||||
    uint32_t streamNo = getU16(currentMovieOffset);
 | 
			
		||||
    uint32_t chunkType = getU16(currentMovieOffset + 2);
 | 
			
		||||
    uint32_t chunkSize = getU32(currentMovieOffset + 4);
 | 
			
		||||
    const uint16_t STREAM0 = 0x3030;
 | 
			
		||||
    const uint16_t TYPEDC = 0x6364;
 | 
			
		||||
 | 
			
		||||
    bool isCurrentFrameLast;
 | 
			
		||||
    //play frame if we have it all
 | 
			
		||||
    if (currentMovieOffset + 8 + chunkSize < movieLength)
 | 
			
		||||
    {
 | 
			
		||||
        if (streamNo == STREAM0 && chunkType == TYPEDC && chunkSize > 0)
 | 
			
		||||
        {
 | 
			
		||||
            currentMovieOffset += 8;
 | 
			
		||||
            //decode frame
 | 
			
		||||
            const uint8_t* chunk = readData(currentMovieOffset, chunkSize);
 | 
			
		||||
            decodeMJPEGFrame(chunk, chunkSize, buffer, buffer_width, buffer_height, buffer_stride);
 | 
			
		||||
            frameNumber++;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        isCurrentFrameLast = false;
 | 
			
		||||
 | 
			
		||||
        // Advance to next frame
 | 
			
		||||
        currentMovieOffset += chunkSize;
 | 
			
		||||
        if (chunkSize == 0) // Skip empty frame
 | 
			
		||||
        {
 | 
			
		||||
            currentMovieOffset += 8;
 | 
			
		||||
        }
 | 
			
		||||
        currentMovieOffset = (currentMovieOffset + 1) & 0xFFFFFFFE; //pad to next word
 | 
			
		||||
 | 
			
		||||
        if (currentMovieOffset == lastFrameEnd)
 | 
			
		||||
        {
 | 
			
		||||
            frameNumber = 1;
 | 
			
		||||
            currentMovieOffset = firstFrameOffset; //start over
 | 
			
		||||
            isCurrentFrameLast = true;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        frameNumber = 1;
 | 
			
		||||
        currentMovieOffset = firstFrameOffset; //start over
 | 
			
		||||
        isCurrentFrameLast = true;
 | 
			
		||||
    }
 | 
			
		||||
    return !isCurrentFrameLast;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool SoftwareMJPEGDecoder::gotoNextFrame()
 | 
			
		||||
{
 | 
			
		||||
    assert((frameNumber > 0) && "SoftwareMJPEGDecoder decoding without frame data!");
 | 
			
		||||
 | 
			
		||||
    readData(currentMovieOffset, 8);
 | 
			
		||||
    uint32_t chunkSize = getU32(currentMovieOffset + 4);
 | 
			
		||||
 | 
			
		||||
    //increment until next video frame
 | 
			
		||||
    while (currentMovieOffset + 8 + chunkSize < movieLength)
 | 
			
		||||
    {
 | 
			
		||||
        //increment one frame
 | 
			
		||||
        currentMovieOffset += chunkSize + 8;
 | 
			
		||||
        currentMovieOffset = (currentMovieOffset + 1) & 0xFFFFFFFE; //pad to next word
 | 
			
		||||
        frameNumber++;
 | 
			
		||||
 | 
			
		||||
        //next chunk
 | 
			
		||||
        readData(currentMovieOffset, 8);
 | 
			
		||||
        //check it is a video frame
 | 
			
		||||
        uint32_t streamNo = getU16(currentMovieOffset);
 | 
			
		||||
        uint32_t chunkType = getU16(currentMovieOffset + 2);
 | 
			
		||||
        chunkSize = getU32(currentMovieOffset + 4);
 | 
			
		||||
        const uint16_t STREAM0 = 0x3030;
 | 
			
		||||
        const uint16_t TYPEDC = 0x6364;
 | 
			
		||||
 | 
			
		||||
        if (streamNo == STREAM0 && chunkType == TYPEDC && chunkSize > 0)
 | 
			
		||||
        {
 | 
			
		||||
            // Found next frame
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    //skip back to first frame
 | 
			
		||||
    frameNumber = 1;
 | 
			
		||||
    currentMovieOffset = firstFrameOffset; //start over
 | 
			
		||||
    return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void SoftwareMJPEGDecoder::setVideoData(const uint8_t* movie, const uint32_t length)
 | 
			
		||||
{
 | 
			
		||||
    movieData = movie;
 | 
			
		||||
    movieLength = length;
 | 
			
		||||
    reader = 0; //not using reader
 | 
			
		||||
 | 
			
		||||
    readVideoHeader();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void SoftwareMJPEGDecoder::setVideoData(touchgfx::VideoDataReader& reader)
 | 
			
		||||
{
 | 
			
		||||
    this->reader = &reader;
 | 
			
		||||
    movieData = 0;
 | 
			
		||||
    movieLength = reader.getDataLength();
 | 
			
		||||
 | 
			
		||||
    readVideoHeader();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool SoftwareMJPEGDecoder::hasVideo()
 | 
			
		||||
{
 | 
			
		||||
    return (reader != 0) || (movieData != 0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void SoftwareMJPEGDecoder::readVideoHeader()
 | 
			
		||||
{
 | 
			
		||||
    // Start from the start
 | 
			
		||||
    currentMovieOffset = 0;
 | 
			
		||||
    lastError = AVI_NO_ERROR;
 | 
			
		||||
 | 
			
		||||
    // Make header available in buffer
 | 
			
		||||
    readData(0, 72);
 | 
			
		||||
 | 
			
		||||
    // Decode the movie header to find first frame
 | 
			
		||||
    // Must be RIFF file
 | 
			
		||||
    if (compare(currentMovieOffset, "RIFF", 4))
 | 
			
		||||
    {
 | 
			
		||||
        lastError = AVI_ERROR_NOT_RIFF;
 | 
			
		||||
        assert(!"RIFF header not found");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    //skip fourcc and length
 | 
			
		||||
    currentMovieOffset += 8;
 | 
			
		||||
    if (compare(currentMovieOffset, "AVI ", 4))
 | 
			
		||||
    {
 | 
			
		||||
        lastError = AVI_ERROR_AVI_HEADER_NOT_FOUND;
 | 
			
		||||
        assert(!"AVI header not found");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    currentMovieOffset += 4;
 | 
			
		||||
    if (compare(currentMovieOffset, "LIST", 4))
 | 
			
		||||
    {
 | 
			
		||||
        lastError = AVI_ERROR_AVI_LIST_NOT_FOUND;
 | 
			
		||||
        assert(!"AVI LIST not found");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    //save AVI List info
 | 
			
		||||
    const uint32_t aviListSize = getU32(currentMovieOffset + 4);
 | 
			
		||||
    const uint32_t aviListOffset = currentMovieOffset;
 | 
			
		||||
    assert(aviListSize);
 | 
			
		||||
 | 
			
		||||
    //look into header to find frame rate
 | 
			
		||||
    bool foundFrame = true;
 | 
			
		||||
    uint32_t offset = currentMovieOffset + 8;
 | 
			
		||||
    if (compare(offset, "hdrl", 4))
 | 
			
		||||
    {
 | 
			
		||||
        lastError = AVI_ERROR_AVI_HDRL_NOT_FOUND;
 | 
			
		||||
        foundFrame = false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    offset += 4;
 | 
			
		||||
    if (compare(offset, "avih", 4))
 | 
			
		||||
    {
 | 
			
		||||
        lastError = AVI_ERROR_AVI_AVIH_NOT_FOUND;
 | 
			
		||||
        foundFrame = false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (foundFrame)
 | 
			
		||||
    {
 | 
			
		||||
        offset += 8; //skip fourcc and cb in AVIMAINHEADER
 | 
			
		||||
        videoInfo.ms_between_frames = getU32(offset) / 1000;
 | 
			
		||||
        videoInfo.number_of_frames = getU32(offset + 16);
 | 
			
		||||
        videoInfo.frame_width = getU32(offset + 32);
 | 
			
		||||
        videoInfo.frame_height = getU32(offset + 36);
 | 
			
		||||
    }
 | 
			
		||||
    //skip rest of AVI header, start from end of AVI List
 | 
			
		||||
 | 
			
		||||
    //look for list with 'movi' header
 | 
			
		||||
    uint32_t listOffset = aviListOffset + aviListSize + 8;
 | 
			
		||||
    readData(listOffset, 12);
 | 
			
		||||
    while (compare(listOffset + 8, "movi", 4) && (lastError == AVI_NO_ERROR) && listOffset < movieLength)
 | 
			
		||||
    {
 | 
			
		||||
        const uint32_t listSize = getU32(listOffset + 4) + 8;
 | 
			
		||||
        listOffset += listSize;
 | 
			
		||||
        readData(listOffset, 12);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (lastError != AVI_NO_ERROR)
 | 
			
		||||
    {
 | 
			
		||||
        lastError = AVI_ERROR_MOVI_NOT_FOUND;
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    //save first frame and end of last frame
 | 
			
		||||
    currentMovieOffset = listOffset + 8 + 4; //skip LIST and 'movi'
 | 
			
		||||
    lastFrameEnd = listOffset + 8 + getU32(listOffset + 4);
 | 
			
		||||
 | 
			
		||||
    //find idx
 | 
			
		||||
    const uint32_t listSize = getU32(listOffset + 4) + 8;
 | 
			
		||||
    listOffset += listSize;
 | 
			
		||||
    readData(listOffset, 4);
 | 
			
		||||
    if (!compare(listOffset, "idx1", 4))
 | 
			
		||||
    {
 | 
			
		||||
        indexOffset = listOffset;
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        lastError = AVI_ERROR_IDX1_NOT_FOUND;
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    //start on first frame
 | 
			
		||||
    frameNumber = 1; //next frame number is 1
 | 
			
		||||
    firstFrameOffset = currentMovieOffset;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#if VIDEO_DECODE_FORMAT == 16 || VIDEO_DECODE_FORMAT == 24 || VIDEO_DECODE_FORMAT == 32
 | 
			
		||||
void SoftwareMJPEGDecoder::decodeMJPEGFrame(const uint8_t* const mjpgdata, const uint32_t length, uint8_t* outputBuffer, uint16_t bufferWidth, uint16_t bufferHeight, uint32_t bufferStride)
 | 
			
		||||
{
 | 
			
		||||
    if (length == 0)
 | 
			
		||||
    {
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (outputBuffer && lineBuffer) //only decode if buffers are assigned.
 | 
			
		||||
    {
 | 
			
		||||
        /* This struct contains the JPEG decompression parameters */
 | 
			
		||||
        struct jpeg_decompress_struct cinfo;
 | 
			
		||||
        /* This struct represents a JPEG error handler */
 | 
			
		||||
        struct jpeg_error_mgr jerr;
 | 
			
		||||
 | 
			
		||||
        JSAMPROW lines[2] = { lineBuffer, 0 }; /* Output row buffer */
 | 
			
		||||
 | 
			
		||||
        /* Step 1: allocate and initialize JPEG decompression object */
 | 
			
		||||
        cinfo.err = jpeg_std_error(&jerr);
 | 
			
		||||
 | 
			
		||||
        /* Initialize the JPEG decompression object */
 | 
			
		||||
        jpeg_create_decompress(&cinfo);
 | 
			
		||||
 | 
			
		||||
        //jpeg_stdio_src (&cinfo, file);
 | 
			
		||||
        jpeg_mem_src(&cinfo, const_cast<uint8_t*>(mjpgdata), length);
 | 
			
		||||
 | 
			
		||||
        /* Step 3: read image parameters with jpeg_read_header() */
 | 
			
		||||
        jpeg_read_header(&cinfo, TRUE);
 | 
			
		||||
 | 
			
		||||
        /* Step 4: set parameters for decompression */
 | 
			
		||||
        cinfo.dct_method = JDCT_FLOAT;
 | 
			
		||||
 | 
			
		||||
        /* Step 5: start decompressor */
 | 
			
		||||
        jpeg_start_decompress(&cinfo);
 | 
			
		||||
 | 
			
		||||
        //restrict to minimum of movie and output buffer size
 | 
			
		||||
        const uint32_t width = MIN(bufferWidth, cinfo.image_width);
 | 
			
		||||
        const uint32_t height = MIN(bufferHeight, cinfo.output_height);
 | 
			
		||||
 | 
			
		||||
#if VIDEO_DECODE_FORMAT == 16
 | 
			
		||||
        uint16_t* lineptr = reinterpret_cast<uint16_t*>(outputBuffer);
 | 
			
		||||
#elif VIDEO_DECODE_FORMAT == 24
 | 
			
		||||
        uint8_t* lineptr = outputBuffer;
 | 
			
		||||
#else
 | 
			
		||||
        uint32_t* lineptr = reinterpret_cast<uint32_t*>(outputBuffer);
 | 
			
		||||
#endif
 | 
			
		||||
        while (cinfo.output_scanline < height)
 | 
			
		||||
        {
 | 
			
		||||
            (void)jpeg_read_scanlines(&cinfo, lines, 1);
 | 
			
		||||
#if VIDEO_DECODE_FORMAT == 16
 | 
			
		||||
            JPEG_RGB* RGB_matrix = (JPEG_RGB*)lineBuffer;
 | 
			
		||||
            JPEG_RGB* const RGB_end = RGB_matrix + width;
 | 
			
		||||
            while (RGB_matrix < RGB_end)
 | 
			
		||||
            {
 | 
			
		||||
                const uint16_t pix = ((RGB_matrix->R & 0xF8) << 8) | ((RGB_matrix->G & 0xFC) << 3) | ((RGB_matrix->B & 0xF8) >> 3);
 | 
			
		||||
                *lineptr++ = pix;
 | 
			
		||||
                RGB_matrix++;
 | 
			
		||||
            }
 | 
			
		||||
            lineptr = (uint16_t*)((uint8_t*)lineptr + bufferStride - width * 2); //move to next line
 | 
			
		||||
#elif VIDEO_DECODE_FORMAT == 24
 | 
			
		||||
            memcpy(lineptr, lineBuffer, width * 3);
 | 
			
		||||
            lineptr += bufferStride; //move to next line
 | 
			
		||||
#else
 | 
			
		||||
            JPEG_RGB* RGB_matrix = (JPEG_RGB*)lineBuffer;
 | 
			
		||||
            JPEG_RGB* const RGB_end = RGB_matrix + width;
 | 
			
		||||
            while (RGB_matrix < RGB_end)
 | 
			
		||||
            {
 | 
			
		||||
                const uint32_t pix = (0xFF << 24) | (RGB_matrix->R << 16) | (RGB_matrix->G << 8) | (RGB_matrix->B);
 | 
			
		||||
                *lineptr++ = pix;
 | 
			
		||||
                RGB_matrix++;
 | 
			
		||||
            }
 | 
			
		||||
            lineptr = (uint32_t*)((uint8_t*)lineptr + bufferStride - width * 4); //move to next line
 | 
			
		||||
#endif
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
#ifdef SIMULATOR
 | 
			
		||||
        cinfo.output_scanline = cinfo.output_height;
 | 
			
		||||
#endif
 | 
			
		||||
        /* Step 6: Finish decompression */
 | 
			
		||||
        jpeg_finish_decompress(&cinfo);
 | 
			
		||||
 | 
			
		||||
        /* Step 7: Release JPEG decompression object */
 | 
			
		||||
        jpeg_destroy_decompress(&cinfo);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool SoftwareMJPEGDecoder::decodeFrame(const touchgfx::Rect& area, uint8_t* frameBuffer, uint32_t framebuffer_width)
 | 
			
		||||
{
 | 
			
		||||
    // Assuming that chunk is available and streamNo and chunkType is correct.
 | 
			
		||||
    // Check by gotoNextFrame
 | 
			
		||||
 | 
			
		||||
    readData(currentMovieOffset, 8);
 | 
			
		||||
    const uint32_t length = getU32(currentMovieOffset + 4);
 | 
			
		||||
 | 
			
		||||
    // Ensure whole frame is read
 | 
			
		||||
    const uint8_t* mjpgdata = readData(currentMovieOffset + 8, length);
 | 
			
		||||
 | 
			
		||||
    assert(lineBuffer && "LineBuffer must be assigned prior to decoding directly to framebuffer");
 | 
			
		||||
 | 
			
		||||
    /* This struct contains the JPEG decompression parameters */
 | 
			
		||||
    struct jpeg_decompress_struct cinfo;
 | 
			
		||||
    /* This struct represents a JPEG error handler */
 | 
			
		||||
    struct jpeg_error_mgr jerr;
 | 
			
		||||
 | 
			
		||||
    JSAMPROW lines[2] = { lineBuffer, 0 }; /* Output row buffer */
 | 
			
		||||
 | 
			
		||||
    /* Step 1: allocate and initialize JPEG decompression object */
 | 
			
		||||
    cinfo.err = jpeg_std_error(&jerr);
 | 
			
		||||
 | 
			
		||||
    /* Initialize the JPEG decompression object */
 | 
			
		||||
    jpeg_create_decompress(&cinfo);
 | 
			
		||||
 | 
			
		||||
    //jpeg_stdio_src (&cinfo, file);
 | 
			
		||||
    jpeg_mem_src(&cinfo, const_cast<uint8_t*>(mjpgdata), length);
 | 
			
		||||
 | 
			
		||||
    /* Step 3: read image parameters with jpeg_read_header() */
 | 
			
		||||
    jpeg_read_header(&cinfo, TRUE);
 | 
			
		||||
 | 
			
		||||
    /* Step 4: set parameters for decompression */
 | 
			
		||||
    cinfo.dct_method = JDCT_FLOAT;
 | 
			
		||||
 | 
			
		||||
    /* Step 5: start decompressor */
 | 
			
		||||
    jpeg_start_decompress(&cinfo);
 | 
			
		||||
 | 
			
		||||
    //restrict to minimum of movie and output buffer size
 | 
			
		||||
    const uint32_t startY = area.y;
 | 
			
		||||
 | 
			
		||||
    //scan down to startY
 | 
			
		||||
    while (cinfo.output_scanline < startY)
 | 
			
		||||
    {
 | 
			
		||||
        (void)jpeg_read_scanlines(&cinfo, lines, 1);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const uint32_t startX = area.x;
 | 
			
		||||
    const uint32_t endX = MIN((uint32_t)area.right(), cinfo.image_width);
 | 
			
		||||
 | 
			
		||||
#if VIDEO_DECODE_FORMAT == 16
 | 
			
		||||
    uint16_t* lineptr = reinterpret_cast<uint16_t*>(frameBuffer);
 | 
			
		||||
    lineptr += framebuffer_width * startY;
 | 
			
		||||
#elif VIDEO_DECODE_FORMAT == 24
 | 
			
		||||
    uint8_t* lineptr = frameBuffer;
 | 
			
		||||
    lineptr += framebuffer_width * 3 * startY;
 | 
			
		||||
#else
 | 
			
		||||
    uint32_t* lineptr = reinterpret_cast<uint32_t*>(frameBuffer);
 | 
			
		||||
    lineptr += framebuffer_width * startY;
 | 
			
		||||
#endif
 | 
			
		||||
    const uint32_t endY = MIN((uint32_t)area.bottom(), cinfo.output_height);
 | 
			
		||||
 | 
			
		||||
    //scan relevant part
 | 
			
		||||
    while (cinfo.output_scanline < endY)
 | 
			
		||||
    {
 | 
			
		||||
        (void)jpeg_read_scanlines(&cinfo, lines, 1);
 | 
			
		||||
#if VIDEO_DECODE_FORMAT == 16
 | 
			
		||||
        JPEG_RGB* RGB_matrix = (JPEG_RGB*)lineBuffer;
 | 
			
		||||
        //loop row RGB888->RGB565 for required line part
 | 
			
		||||
        for (uint32_t counter = startX; counter < endX; counter++)
 | 
			
		||||
        {
 | 
			
		||||
            const uint16_t pix = ((RGB_matrix[counter].R & 0xF8) << 8) | ((RGB_matrix[counter].G & 0xFC) << 3) | ((RGB_matrix[counter].B & 0xF8) >> 3);
 | 
			
		||||
            *(lineptr + counter) = pix;
 | 
			
		||||
        }
 | 
			
		||||
        lineptr += framebuffer_width; //move to next line
 | 
			
		||||
#elif VIDEO_DECODE_FORMAT == 24
 | 
			
		||||
        memcpy(lineptr + startX * 3, lineBuffer + startX * 3, (endX - startX) * 3);
 | 
			
		||||
        lineptr += framebuffer_width * 3; //move to next line
 | 
			
		||||
#else
 | 
			
		||||
        memcpy(lineptr + startX, lineBuffer + startX * 4, (endX - startX) * 4);
 | 
			
		||||
        lineptr += framebuffer_width; //move to next line
 | 
			
		||||
#endif
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#ifdef SIMULATOR
 | 
			
		||||
    cinfo.output_scanline = cinfo.output_height;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    /* Step 6: Finish decompression */
 | 
			
		||||
    jpeg_finish_decompress(&cinfo);
 | 
			
		||||
 | 
			
		||||
    /* Step 7: Release JPEG decompression object */
 | 
			
		||||
    jpeg_destroy_decompress(&cinfo);
 | 
			
		||||
 | 
			
		||||
    return true;
 | 
			
		||||
}
 | 
			
		||||
#else
 | 
			
		||||
void SoftwareMJPEGDecoder::decodeMJPEGFrame(const uint8_t* const, const uint32_t, uint8_t*, uint16_t, uint16_t, uint32_t)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
bool SoftwareMJPEGDecoder::decodeFrame(const touchgfx::Rect&, uint8_t*, uint32_t)
 | 
			
		||||
{
 | 
			
		||||
    return true;
 | 
			
		||||
}
 | 
			
		||||
#endif // VIDEO_DECODE_FORMAT == 16 || VIDEO_DECODE_FORMAT == 24 || VIDEO_DECODE_FORMAT == 32
 | 
			
		||||
 | 
			
		||||
bool SoftwareMJPEGDecoder::decodeThumbnail(uint32_t frameno, uint8_t* buffer, uint16_t width, uint16_t height)
 | 
			
		||||
{
 | 
			
		||||
    assert(0);
 | 
			
		||||
    return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void SoftwareMJPEGDecoder::gotoFrame(uint32_t frameNumber)
 | 
			
		||||
{
 | 
			
		||||
    if (frameNumber == 0)
 | 
			
		||||
    {
 | 
			
		||||
        frameNumber = 1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (frameNumber > getNumberOfFrames())
 | 
			
		||||
    {
 | 
			
		||||
        frameNumber = getNumberOfFrames();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    uint32_t offset = indexOffset + 8 + (frameNumber - 1) * 16;
 | 
			
		||||
 | 
			
		||||
    readData(offset, 16);
 | 
			
		||||
 | 
			
		||||
    currentMovieOffset = getU32(offset + 8) + firstFrameOffset - 4;
 | 
			
		||||
    this->frameNumber = frameNumber;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
uint32_t SoftwareMJPEGDecoder::getNumberOfFrames()
 | 
			
		||||
{
 | 
			
		||||
    return videoInfo.number_of_frames;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void SoftwareMJPEGDecoder::getVideoInfo(touchgfx::VideoInformation* data)
 | 
			
		||||
{
 | 
			
		||||
    *data = videoInfo;
 | 
			
		||||
    // For unsupported decode formats, set video dimension to 0x0, to avoid drawing anything
 | 
			
		||||
#if VIDEO_DECODE_FORMAT == 16 || VIDEO_DECODE_FORMAT == 24 || VIDEO_DECODE_FORMAT == 32
 | 
			
		||||
#else
 | 
			
		||||
    data->frame_width = 0;
 | 
			
		||||
    data->frame_height = 0;
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										
											BIN
										
									
								
								TouchGFX/generated/simulator/touchgfx.ico
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								TouchGFX/generated/simulator/touchgfx.ico
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 375 KiB  | 
							
								
								
									
										1
									
								
								TouchGFX/generated/simulator/touchgfx.rc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								TouchGFX/generated/simulator/touchgfx.rc
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1 @@
 | 
			
		||||
id ICON touchgfx.ico
 | 
			
		||||
							
								
								
									
										
											BIN
										
									
								
								TouchGFX/generated/simulator/touchgfx.res
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								TouchGFX/generated/simulator/touchgfx.res
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
		Reference in New Issue
	
	Block a user