diff --git a/Makefile b/Makefile index 3890b57..f8036e2 100644 --- a/Makefile +++ b/Makefile @@ -5,7 +5,7 @@ SHELL = /bin/bash -o pipefail BASE = arm-linux-gnueabihf CC = $(BASE)-gcc -LD = $(CC) +LD = $(BASE)-ld STRIP = $(BASE)-strip ifeq ($(V),1) @@ -22,6 +22,7 @@ INCLUDE += -I./lib/miniz PRJ = MiSTer SRC = $(wildcard *.c) SRC2 = $(wildcard *.cpp) +IMG = $(wildcard *.png) MINIMIG_SRC = $(wildcard ./support/minimig/*.cpp) SHARPMZ_SRC = $(wildcard ./support/sharpmz/*.cpp) ARCHIE_SRC = $(wildcard ./support/archie/*.cpp) @@ -32,18 +33,20 @@ LIBCO_SRC = lib/libco/arm.c LODEPNG_SRC = lib/lodepng/lodepng.cpp MINIZ_SRC = $(wildcard ./lib/miniz/*.c) +IMLIB2_LIB = -Llib/imlib2 -lfreetype -lbz2 -lpng16 -lz -lImlib2 + VPATH = ./:./support/minimig:./support/sharpmz:./support/archie:./support/st:./support/x86:./support/snes -OBJ = $(SRC:.c=.c.o) $(SRC2:.cpp=.cpp.o) $(MINIMIG_SRC:.cpp=.cpp.o) $(SHARPMZ_SRC:.cpp=.cpp.o) $(ARCHIE_SRC:.cpp=.cpp.o) $(ST_SRC:.cpp=.cpp.o) $(X86_SRC:.cpp=.cpp.o) $(SNES_SRC:.cpp=.cpp.o) $(LIBCO_SRC:.c=.c.o) $(MINIZ_SRC:.c=.c.o) $(LODEPNG_SRC:.cpp=.cpp.o) +OBJ = $(SRC:.c=.c.o) $(SRC2:.cpp=.cpp.o) $(IMG:.png=.png.o) $(MINIMIG_SRC:.cpp=.cpp.o) $(SHARPMZ_SRC:.cpp=.cpp.o) $(ARCHIE_SRC:.cpp=.cpp.o) $(ST_SRC:.cpp=.cpp.o) $(X86_SRC:.cpp=.cpp.o) $(SNES_SRC:.cpp=.cpp.o) $(LIBCO_SRC:.c=.c.o) $(MINIZ_SRC:.c=.c.o) $(LODEPNG_SRC:.cpp=.cpp.o) DEP = $(SRC:.c=.cpp.d) $(SRC2:.cpp=.cpp.d) $(MINIMIG_SRC:.cpp=.cpp.d) $(SHARPMZ_SRC:.cpp=.cpp.d) $(ARCHIE_SRC:.cpp=.cpp.d) $(ST_SRC:.cpp=.cpp.d) $(X86_SRC:.cpp=.cpp.d) $(SNES_SRC:.cpp=.cpp.d) $(LIBCO_SRC:.c=.c.d) $(MINIZ_SRC:.c=.c.d) $(LODEPNG_SRC:.cpp=.cpp.d) DFLAGS = $(INCLUDE) -D_FILE_OFFSET_BITS=64 -D_LARGEFILE64_SOURCE -DVDATE=\"`date +"%y%m%d"`\" CFLAGS = $(DFLAGS) -Wall -Wextra -Wno-strict-aliasing -c -O3 -LFLAGS = -lc -lstdc++ -lrt +LFLAGS = -lc -lstdc++ -lrt $(IMLIB2_LIB) $(PRJ): $(OBJ) $(Q)$(info $@) - $(Q)$(LD) -o $@ $+ $(LFLAGS) + $(Q)$(CC) -o $@ $+ $(LFLAGS) $(Q)cp $@ $@.elf $(Q)$(STRIP) $@ @@ -66,6 +69,10 @@ cleanall: $(Q)$(info $<) $(Q)$(CC) $(CFLAGS) -std=gnu++14 -o $@ -c $< 2>&1 | sed -e 's/\(.[a-zA-Z]\+\):\([0-9]\+\):\([0-9]\+\):/\1(\2,\ \3):/g' +%.png.o: %.png + $(Q)$(info $<) + $(Q)$(LD) -r -b binary -o $@ $< 2>&1 | sed -e 's/\(.[a-zA-Z]\+\):\([0-9]\+\):\([0-9]\+\):/\1(\2,\ \3):/g' + -include $(DEP) %.c.d: %.c $(Q)$(CC) $(DFLAGS) -MM $< -MT $@ -MT $*.c.o -MF $@ 2>&1 | sed -e 's/\(.[a-zA-Z]\+\):\([0-9]\+\):\([0-9]\+\):/\1(\2,\ \3):/g' diff --git a/MiSTer.ini b/MiSTer.ini index a6d3368..cb1f63e 100644 --- a/MiSTer.ini +++ b/MiSTer.ini @@ -17,6 +17,7 @@ vscale_border=0 ; set vertical border for TVs cutting the upper/bottom pa rbf_hide_datecode=0 ; 1 - hides datecodes from rbf file names. Press F2 for quick temporary toggle menu_pal=0 ; 1 - PAL mode for menu core hdmi_limited=0 ; 1 - use limited (16..235) color range over HDMI +fb_size=0 ; 0 - automatic, 1 - full size, 2 - 1/2 of resolution, 4 - 1/4 of resolution. ; lastcore - Autoboot the last loaded core (corename autosaved in CONFIG/lastcore.dat) first found on the SD/USB ; lastexactcore - Autoboot the last loaded exact core (corename_yyyymmdd.rbf autosaved in CONFIG/lastcore.dat) first found on the SD/USB diff --git a/MiSTer.vcxproj b/MiSTer.vcxproj index 5f9a3a9..93ca23e 100644 --- a/MiSTer.vcxproj +++ b/MiSTer.vcxproj @@ -107,6 +107,7 @@ + diff --git a/MiSTer.vcxproj.filters b/MiSTer.vcxproj.filters index 8c36384..8cd303b 100644 --- a/MiSTer.vcxproj.filters +++ b/MiSTer.vcxproj.filters @@ -291,5 +291,8 @@ Header Files + + Header Files + \ No newline at end of file diff --git a/cfg.cpp b/cfg.cpp index 225ffe3..71ea168 100644 --- a/cfg.cpp +++ b/cfg.cpp @@ -13,7 +13,6 @@ void MiSTer_ini_parse() { memset(&cfg, 0, sizeof(cfg)); cfg.bootscreen = 1; - cfg.fb_size = 1; ini_parse(&ini_cfg); } diff --git a/file_io.cpp b/file_io.cpp index 5dddd5e..2c18406 100644 --- a/file_io.cpp +++ b/file_io.cpp @@ -494,9 +494,11 @@ int FileWriteSec(fileTYPE *file, void *pBuffer) return FileWriteAdv(file, pBuffer, 512); } -int FileSave(const char *name, void *pBuffer, int size) +int FileSave(const char *name, void *pBuffer, int size, int sys) { - sprintf(full_path, "%s/%s", getRootDir(), name); + if(!sys) sprintf(full_path, "%s/%s", getRootDir(), name); + else strcpy(full_path, name); + int fd = open(full_path, O_WRONLY | O_CREAT | O_TRUNC | O_SYNC, S_IRWXU | S_IRWXG | S_IRWXO); if (fd < 0) { @@ -523,9 +525,11 @@ int FileSaveConfig(const char *name, void *pBuffer, int size) return FileSave(path, pBuffer, size); } -int FileLoad(const char *name, void *pBuffer, int size) +int FileLoad(const char *name, void *pBuffer, int size, int sys) { - sprintf(full_path, "%s/%s", getRootDir(), name); + if (!sys) sprintf(full_path, "%s/%s", getRootDir(), name); + else strcpy(full_path, name); + int fd = open(full_path, O_RDONLY); if (fd < 0) { @@ -567,6 +571,12 @@ int FileLoadConfig(const char *name, void *pBuffer, int size) return FileLoad(path, pBuffer, size); } +int FileExists(const char *name) +{ + sprintf(full_path, "%s/%s", getRootDir(), name); + return !access(full_path, F_OK); +} + int FileCanWrite(const char *name) { sprintf(full_path, "%s/%s", getRootDir(), name); diff --git a/file_io.h b/file_io.h index 3762ac5..ef129d2 100644 --- a/file_io.h +++ b/file_io.h @@ -61,6 +61,7 @@ int FileReadSec(fileTYPE *file, void *pBuffer); int FileWriteAdv(fileTYPE *file, void *pBuffer, int length); int FileWriteSec(fileTYPE *file, void *pBuffer); +int FileExists(const char *name); int FileCanWrite(const char *name); #define SAVE_DIR "saves" @@ -70,8 +71,8 @@ void FileGenerateSavePath(const char *name, char* out_name); #define SCREENSHOT_DEFAULT "screen" void FileGenerateScreenshotName(const char *name, char *out_name, int buflen); -int FileSave(const char *name, void *pBuffer, int size); -int FileLoad(const char *name, void *pBuffer, int size); // supply pBuffer = 0 to get the file size without loading +int FileSave(const char *name, void *pBuffer, int size, int sys = 0); +int FileLoad(const char *name, void *pBuffer, int size, int sys = 0); // supply pBuffer = 0 to get the file size without loading //save/load from config dir #define CONFIG_DIR "config" diff --git a/lib/imlib2/Imlib2.h b/lib/imlib2/Imlib2.h new file mode 100644 index 0000000..35d3007 --- /dev/null +++ b/lib/imlib2/Imlib2.h @@ -0,0 +1,596 @@ +#ifndef __IMLIB_API_H +#define __IMLIB_API_H 1 + +#ifdef EAPI +#undef EAPI +#endif +#ifdef WIN32 +#ifdef BUILDING_DLL +#define EAPI __declspec(dllexport) +#else +#define EAPI __declspec(dllimport) +#endif +#else +#ifdef __GNUC__ +#if __GNUC__ >= 4 +#define EAPI __attribute__ ((visibility("default"))) +#else +#define EAPI +#endif +#else +#define EAPI +#endif +#endif + +#define X_DISPLAY_MISSING + +#ifndef X_DISPLAY_MISSING +#include +#endif + +/* Data types to use */ +#ifndef DATA64 +#define DATA64 unsigned long long +#define DATA32 unsigned int +#define DATA16 unsigned short +#define DATA8 unsigned char +#endif + +/* opaque data types */ +typedef void *Imlib_Context; +typedef void *Imlib_Image; +typedef void *Imlib_Color_Modifier; +typedef void *Imlib_Updates; +typedef void *Imlib_Font; +typedef void *Imlib_Color_Range; +typedef void *Imlib_Filter; +typedef struct _imlib_border Imlib_Border; +typedef struct _imlib_color Imlib_Color; +typedef void *ImlibPolygon; + +/* blending operations */ +enum _imlib_operation { + IMLIB_OP_COPY, + IMLIB_OP_ADD, + IMLIB_OP_SUBTRACT, + IMLIB_OP_RESHADE +}; + +enum _imlib_text_direction { + IMLIB_TEXT_TO_RIGHT = 0, + IMLIB_TEXT_TO_LEFT = 1, + IMLIB_TEXT_TO_DOWN = 2, + IMLIB_TEXT_TO_UP = 3, + IMLIB_TEXT_TO_ANGLE = 4 +}; + +enum _imlib_load_error { + IMLIB_LOAD_ERROR_NONE, + IMLIB_LOAD_ERROR_FILE_DOES_NOT_EXIST, + IMLIB_LOAD_ERROR_FILE_IS_DIRECTORY, + IMLIB_LOAD_ERROR_PERMISSION_DENIED_TO_READ, + IMLIB_LOAD_ERROR_NO_LOADER_FOR_FILE_FORMAT, + IMLIB_LOAD_ERROR_PATH_TOO_LONG, + IMLIB_LOAD_ERROR_PATH_COMPONENT_NON_EXISTANT, + IMLIB_LOAD_ERROR_PATH_COMPONENT_NOT_DIRECTORY, + IMLIB_LOAD_ERROR_PATH_POINTS_OUTSIDE_ADDRESS_SPACE, + IMLIB_LOAD_ERROR_TOO_MANY_SYMBOLIC_LINKS, + IMLIB_LOAD_ERROR_OUT_OF_MEMORY, + IMLIB_LOAD_ERROR_OUT_OF_FILE_DESCRIPTORS, + IMLIB_LOAD_ERROR_PERMISSION_DENIED_TO_WRITE, + IMLIB_LOAD_ERROR_OUT_OF_DISK_SPACE, + IMLIB_LOAD_ERROR_UNKNOWN +}; + +/* Encodings known to Imlib2 (so far) */ +enum _imlib_TTF_encoding { + IMLIB_TTF_ENCODING_ISO_8859_1, + IMLIB_TTF_ENCODING_ISO_8859_2, + IMLIB_TTF_ENCODING_ISO_8859_3, + IMLIB_TTF_ENCODING_ISO_8859_4, + IMLIB_TTF_ENCODING_ISO_8859_5 +}; + +typedef enum _imlib_operation Imlib_Operation; +typedef enum _imlib_load_error Imlib_Load_Error; +typedef enum _imlib_text_direction Imlib_Text_Direction; +typedef enum _imlib_TTF_encoding Imlib_TTF_Encoding; + +struct _imlib_border { + int left, right, top, bottom; +}; + +struct _imlib_color { + int alpha, red, green, blue; +}; + +/* Progressive loading callbacks */ +typedef int (*Imlib_Progress_Function) (Imlib_Image im, char percent, + int update_x, int update_y, + int update_w, int update_h); +typedef void (*Imlib_Data_Destructor_Function) (Imlib_Image im, + void *data); + +/* *INDENT-OFF* */ +#ifdef __cplusplus +extern "C" { +#endif +/* *INDENT-ON* */ + +/* context handling */ +EAPI Imlib_Context imlib_context_new(void); +EAPI void imlib_context_free(Imlib_Context context); + +EAPI void imlib_context_push(Imlib_Context context); +EAPI void imlib_context_pop(void); +EAPI Imlib_Context imlib_context_get(void); + +/* context setting */ +#ifndef X_DISPLAY_MISSING +EAPI void imlib_context_set_display(Display * display); +EAPI void imlib_context_disconnect_display(void); +EAPI void imlib_context_set_visual(Visual * visual); +EAPI void imlib_context_set_colormap(Colormap colormap); +EAPI void imlib_context_set_drawable(Drawable drawable); +EAPI void imlib_context_set_mask(Pixmap mask); +#endif +EAPI void imlib_context_set_dither_mask(char dither_mask); +EAPI void imlib_context_set_mask_alpha_threshold(int + mask_alpha_threshold); +EAPI void imlib_context_set_anti_alias(char anti_alias); +EAPI void imlib_context_set_dither(char dither); +EAPI void imlib_context_set_blend(char blend); +EAPI void imlib_context_set_color_modifier(Imlib_Color_Modifier + color_modifier); +EAPI void imlib_context_set_operation(Imlib_Operation operation); +EAPI void imlib_context_set_font(Imlib_Font font); +EAPI void imlib_context_set_direction(Imlib_Text_Direction direction); +EAPI void imlib_context_set_angle(double angle); +EAPI void imlib_context_set_color(int red, int green, int blue, + int alpha); +EAPI void imlib_context_set_color_hsva(float hue, float saturation, + float value, int alpha); +EAPI void imlib_context_set_color_hlsa(float hue, float lightness, + float saturation, int alpha); +EAPI void imlib_context_set_color_cmya(int cyan, int magenta, + int yellow, int alpha); +EAPI void imlib_context_set_color_range(Imlib_Color_Range + color_range); +EAPI void imlib_context_set_progress_function(Imlib_Progress_Function + progress_function); +EAPI void imlib_context_set_progress_granularity(char + progress_granularity); +EAPI void imlib_context_set_image(Imlib_Image image); +EAPI void imlib_context_set_cliprect(int x, int y, int w, int h); +EAPI void imlib_context_set_TTF_encoding(Imlib_TTF_Encoding encoding); + +/* context getting */ +#ifndef X_DISPLAY_MISSING +EAPI Display *imlib_context_get_display(void); +EAPI Visual *imlib_context_get_visual(void); +EAPI Colormap imlib_context_get_colormap(void); +EAPI Drawable imlib_context_get_drawable(void); +EAPI Pixmap imlib_context_get_mask(void); +#endif +EAPI char imlib_context_get_dither_mask(void); +EAPI char imlib_context_get_anti_alias(void); +EAPI int imlib_context_get_mask_alpha_threshold(void); +EAPI char imlib_context_get_dither(void); +EAPI char imlib_context_get_blend(void); +EAPI Imlib_Color_Modifier imlib_context_get_color_modifier(void); +EAPI Imlib_Operation imlib_context_get_operation(void); +EAPI Imlib_Font imlib_context_get_font(void); +EAPI double imlib_context_get_angle(void); +EAPI Imlib_Text_Direction imlib_context_get_direction(void); +EAPI void imlib_context_get_color(int *red, int *green, int *blue, + int *alpha); +EAPI void imlib_context_get_color_hsva(float *hue, float *saturation, + float *value, int *alpha); +EAPI void imlib_context_get_color_hlsa(float *hue, float *lightness, + float *saturation, int *alpha); +EAPI void imlib_context_get_color_cmya(int *cyan, int *magenta, + int *yellow, int *alpha); +EAPI Imlib_Color *imlib_context_get_imlib_color(void); +EAPI Imlib_Color_Range imlib_context_get_color_range(void); +EAPI Imlib_Progress_Function imlib_context_get_progress_function(void); +EAPI char imlib_context_get_progress_granularity(void); +EAPI Imlib_Image imlib_context_get_image(void); +EAPI void imlib_context_get_cliprect(int *x, int *y, int *w, int *h); +EAPI Imlib_TTF_Encoding imlib_context_get_TTF_encoding(void); + +EAPI int imlib_get_cache_size(void); +EAPI void imlib_set_cache_size(int bytes); +EAPI int imlib_get_color_usage(void); +EAPI void imlib_set_color_usage(int max); +EAPI void imlib_flush_loaders(void); + +#ifndef X_DISPLAY_MISSING +EAPI int imlib_get_visual_depth(Display * display, Visual * visual); +EAPI Visual *imlib_get_best_visual(Display * display, int screen, + int *depth_return); +#endif + +EAPI Imlib_Image imlib_load_image(const char *file); +EAPI Imlib_Image imlib_load_image_immediately(const char *file); +EAPI Imlib_Image imlib_load_image_without_cache(const char *file); +EAPI Imlib_Image imlib_load_image_immediately_without_cache(const char + *file); +EAPI Imlib_Image imlib_load_image_with_error_return(const char *file, + Imlib_Load_Error * + error_return); +EAPI void imlib_free_image(void); +EAPI void imlib_free_image_and_decache(void); + +/* query/modify image parameters */ +EAPI int imlib_image_get_width(void); +EAPI int imlib_image_get_height(void); +EAPI const char *imlib_image_get_filename(void); +EAPI DATA32 *imlib_image_get_data(void); +EAPI DATA32 *imlib_image_get_data_for_reading_only(void); +EAPI void imlib_image_put_back_data(DATA32 * data); +EAPI char imlib_image_has_alpha(void); +EAPI void imlib_image_set_changes_on_disk(void); +EAPI void imlib_image_get_border(Imlib_Border * border); +EAPI void imlib_image_set_border(Imlib_Border * border); +EAPI void imlib_image_set_format(const char *format); +EAPI void imlib_image_set_irrelevant_format(char irrelevant); +EAPI void imlib_image_set_irrelevant_border(char irrelevant); +EAPI void imlib_image_set_irrelevant_alpha(char irrelevant); +EAPI char *imlib_image_format(void); +EAPI void imlib_image_set_has_alpha(char has_alpha); +EAPI void imlib_image_query_pixel(int x, int y, + Imlib_Color * color_return); +EAPI void imlib_image_query_pixel_hsva(int x, int y, float *hue, + float *saturation, + float *value, int *alpha); +EAPI void imlib_image_query_pixel_hlsa(int x, int y, float *hue, + float *lightness, + float *saturation, int *alpha); +EAPI void imlib_image_query_pixel_cmya(int x, int y, int *cyan, + int *magenta, int *yellow, + int *alpha); + +/* rendering functions */ +#ifndef X_DISPLAY_MISSING +EAPI void imlib_render_pixmaps_for_whole_image(Pixmap * pixmap_return, + Pixmap * mask_return); +EAPI void imlib_render_pixmaps_for_whole_image_at_size(Pixmap * + pixmap_return, + Pixmap * + mask_return, + int width, + int height); +EAPI void imlib_free_pixmap_and_mask(Pixmap pixmap); +EAPI void imlib_render_image_on_drawable(int x, int y); +EAPI void imlib_render_image_on_drawable_at_size(int x, int y, + int width, + int height); +EAPI void imlib_render_image_part_on_drawable_at_size(int source_x, + int source_y, + int + source_width, int + source_height, + int x, int y, + int width, + int height); +EAPI DATA32 imlib_render_get_pixel_color(void); +#endif +EAPI void imlib_blend_image_onto_image(Imlib_Image source_image, + char merge_alpha, + int source_x, int source_y, + int source_width, + int source_height, + int destination_x, + int destination_y, + int destination_width, + int destination_height); + +/* creation functions */ +EAPI Imlib_Image imlib_create_image(int width, int height); +EAPI Imlib_Image imlib_create_image_using_data(int width, int height, + DATA32 * data); +EAPI Imlib_Image imlib_create_image_using_copied_data(int width, + int height, + DATA32 * data); +#ifndef X_DISPLAY_MISSING +EAPI Imlib_Image imlib_create_image_from_drawable(Pixmap mask, + int x, int y, + int width, int height, + char need_to_grab_x); +EAPI Imlib_Image imlib_create_image_from_ximage(XImage * image, + XImage * mask, + int x, int y, + int width, int height, + char need_to_grab_x); +EAPI Imlib_Image imlib_create_scaled_image_from_drawable(Pixmap mask, + int source_x, + int source_y, + int source_width, + int + source_height, int + destination_width, int + destination_height, char + need_to_grab_x, char + get_mask_from_shape); +EAPI char imlib_copy_drawable_to_image(Pixmap mask, int x, int y, + int width, int height, + int destination_x, + int destination_y, + char need_to_grab_x); +#endif +EAPI Imlib_Image imlib_clone_image(void); +EAPI Imlib_Image imlib_create_cropped_image(int x, int y, int width, + int height); +EAPI Imlib_Image imlib_create_cropped_scaled_image(int source_x, + int source_y, + int source_width, + int source_height, + int destination_width, + int destination_height); + +/* imlib updates. lists of rectangles for storing required update draws */ +EAPI Imlib_Updates imlib_updates_clone(Imlib_Updates updates); +EAPI Imlib_Updates imlib_update_append_rect(Imlib_Updates updates, + int x, int y, int w, int h); +EAPI Imlib_Updates imlib_updates_merge(Imlib_Updates updates, int w, int h); +EAPI Imlib_Updates imlib_updates_merge_for_rendering(Imlib_Updates updates, + int w, int h); +EAPI void imlib_updates_free(Imlib_Updates updates); +EAPI Imlib_Updates imlib_updates_get_next(Imlib_Updates updates); +EAPI void imlib_updates_get_coordinates(Imlib_Updates updates, + int *x_return, + int *y_return, + int *width_return, + int *height_return); +EAPI void imlib_updates_set_coordinates(Imlib_Updates updates, + int x, int y, + int width, int height); +EAPI void imlib_render_image_updates_on_drawable(Imlib_Updates + updates, + int x, int y); +EAPI Imlib_Updates imlib_updates_init(void); +EAPI Imlib_Updates imlib_updates_append_updates(Imlib_Updates updates, + Imlib_Updates + appended_updates); + +/* image modification */ +EAPI void imlib_image_flip_horizontal(void); +EAPI void imlib_image_flip_vertical(void); +EAPI void imlib_image_flip_diagonal(void); +EAPI void imlib_image_orientate(int orientation); +EAPI void imlib_image_blur(int radius); +EAPI void imlib_image_sharpen(int radius); +EAPI void imlib_image_tile_horizontal(void); +EAPI void imlib_image_tile_vertical(void); +EAPI void imlib_image_tile(void); + +/* fonts and text */ +EAPI Imlib_Font imlib_load_font(const char *font_name); +EAPI void imlib_free_font(void); + + /* NB! The four functions below are deprecated. */ +EAPI int imlib_insert_font_into_fallback_chain(Imlib_Font font, + Imlib_Font + fallback_font); +EAPI void imlib_remove_font_from_fallback_chain(Imlib_Font + fallback_font); +EAPI Imlib_Font imlib_get_prev_font_in_fallback_chain(Imlib_Font fn); +EAPI Imlib_Font imlib_get_next_font_in_fallback_chain(Imlib_Font fn); + + /* NB! The four functions above are deprecated. */ +EAPI void imlib_text_draw(int x, int y, const char *text); +EAPI void imlib_text_draw_with_return_metrics(int x, int y, + const char *text, + int *width_return, + int *height_return, int + *horizontal_advance_return, int + *vertical_advance_return); +EAPI void imlib_get_text_size(const char *text, + int *width_return, int *height_return); +EAPI void imlib_get_text_advance(const char *text, + int *horizontal_advance_return, + int *vertical_advance_return); +EAPI int imlib_get_text_inset(const char *text); +EAPI void imlib_add_path_to_font_path(const char *path); +EAPI void imlib_remove_path_from_font_path(const char *path); +EAPI char **imlib_list_font_path(int *number_return); +EAPI int imlib_text_get_index_and_location(const char *text, + int x, int y, + int *char_x_return, + int *char_y_return, + int *char_width_return, + int *char_height_return); +EAPI void imlib_text_get_location_at_index(const char *text, + int index, + int *char_x_return, + int *char_y_return, + int *char_width_return, + int *char_height_return); +EAPI char **imlib_list_fonts(int *number_return); +EAPI void imlib_free_font_list(char **font_list, int number); +EAPI int imlib_get_font_cache_size(void); +EAPI void imlib_set_font_cache_size(int bytes); +EAPI void imlib_flush_font_cache(void); +EAPI int imlib_get_font_ascent(void); +EAPI int imlib_get_font_descent(void); +EAPI int imlib_get_maximum_font_ascent(void); +EAPI int imlib_get_maximum_font_descent(void); + +/* color modifiers */ +EAPI Imlib_Color_Modifier imlib_create_color_modifier(void); +EAPI void imlib_free_color_modifier(void); +EAPI void imlib_modify_color_modifier_gamma(double gamma_value); +EAPI void imlib_modify_color_modifier_brightness(double + brightness_value); +EAPI void imlib_modify_color_modifier_contrast(double + contrast_value); +EAPI void imlib_set_color_modifier_tables(DATA8 * red_table, + DATA8 * green_table, + DATA8 * blue_table, + DATA8 * alpha_table); +EAPI void imlib_get_color_modifier_tables(DATA8 * red_table, + DATA8 * green_table, + DATA8 * blue_table, + DATA8 * alpha_table); +EAPI void imlib_reset_color_modifier(void); +EAPI void imlib_apply_color_modifier(void); +EAPI void imlib_apply_color_modifier_to_rectangle(int x, int y, + int width, + int height); + +/* drawing on images */ +EAPI Imlib_Updates imlib_image_draw_pixel(int x, int y, char make_updates); +EAPI Imlib_Updates imlib_image_draw_line(int x1, int y1, int x2, int y2, + char make_updates); +EAPI void imlib_image_draw_rectangle(int x, int y, + int width, int height); +EAPI void imlib_image_fill_rectangle(int x, int y, + int width, int height); +EAPI void imlib_image_copy_alpha_to_image(Imlib_Image image_source, + int x, int y); +EAPI void imlib_image_copy_alpha_rectangle_to_image(Imlib_Image + image_source, + int x, int y, + int width, + int height, + int destination_x, + int + destination_y); +EAPI void imlib_image_scroll_rect(int x, int y, int width, int height, + int delta_x, int delta_y); +EAPI void imlib_image_copy_rect(int x, int y, int width, int height, + int new_x, int new_y); + +/* polygons */ +EAPI ImlibPolygon imlib_polygon_new(void); +EAPI void imlib_polygon_free(ImlibPolygon poly); +EAPI void imlib_polygon_add_point(ImlibPolygon poly, int x, int y); +EAPI void imlib_image_draw_polygon(ImlibPolygon poly, + unsigned char closed); +EAPI void imlib_image_fill_polygon(ImlibPolygon poly); +EAPI void imlib_polygon_get_bounds(ImlibPolygon poly, + int *px1, int *py1, + int *px2, int *py2); +EAPI unsigned char imlib_polygon_contains_point(ImlibPolygon poly, + int x, int y); + +/* ellipses */ +EAPI void imlib_image_draw_ellipse(int xc, int yc, int a, int b); +EAPI void imlib_image_fill_ellipse(int xc, int yc, int a, int b); + +/* color ranges */ +EAPI Imlib_Color_Range imlib_create_color_range(void); +EAPI void imlib_free_color_range(void); +EAPI void imlib_add_color_to_color_range(int distance_away); +EAPI void imlib_image_fill_color_range_rectangle(int x, int y, + int width, + int height, + double angle); +EAPI void imlib_image_fill_hsva_color_range_rectangle(int x, int y, + int width, + int height, + double + angle); + +/* image data */ +EAPI void imlib_image_attach_data_value(const char *key, + void *data, int value, + Imlib_Data_Destructor_Function + destructor_function); +EAPI void *imlib_image_get_attached_data(const char *key); +EAPI int imlib_image_get_attached_value(const char *key); +EAPI void imlib_image_remove_attached_data_value(const char *key); +EAPI void imlib_image_remove_and_free_attached_data_value(const char + *key); + +/* saving */ +EAPI void imlib_save_image(const char *filename); +EAPI void imlib_save_image_with_error_return(const char *filename, + Imlib_Load_Error * + error_return); + +/* FIXME: */ +/* need to add arbitrary rotation routines */ + +/* rotation/skewing */ +EAPI Imlib_Image imlib_create_rotated_image(double angle); + +/* rotation from buffer to context (without copying)*/ +EAPI void imlib_rotate_image_from_buffer(double angle, + Imlib_Image source_image); + +EAPI void imlib_blend_image_onto_image_at_angle(Imlib_Image + source_image, + char merge_alpha, + int source_x, + int source_y, + int source_width, + int source_height, + int destination_x, + int destination_y, + int angle_x, + int angle_y); +EAPI void imlib_blend_image_onto_image_skewed(Imlib_Image + source_image, + char merge_alpha, + int source_x, + int source_y, + int source_width, + int source_height, + int destination_x, + int destination_y, + int h_angle_x, + int h_angle_y, + int v_angle_x, + int v_angle_y); +#ifndef X_DISPLAY_MISSING +EAPI void imlib_render_image_on_drawable_skewed(int source_x, + int source_y, + int source_width, + int source_height, + int destination_x, + int destination_y, + int h_angle_x, + int h_angle_y, + int v_angle_x, + int v_angle_y); +EAPI void imlib_render_image_on_drawable_at_angle(int source_x, + int source_y, + int source_width, + int source_height, + int destination_x, + int destination_y, + int angle_x, + int angle_y); +#endif + +/* image filters */ +EAPI void imlib_image_filter(void); +EAPI Imlib_Filter imlib_create_filter(int initsize); +EAPI void imlib_context_set_filter(Imlib_Filter filter); +EAPI Imlib_Filter imlib_context_get_filter(void); +EAPI void imlib_free_filter(void); +EAPI void imlib_filter_set(int xoff, int yoff, + int a, int r, int g, int b); +EAPI void imlib_filter_set_alpha(int xoff, int yoff, + int a, int r, int g, int b); +EAPI void imlib_filter_set_red(int xoff, int yoff, + int a, int r, int g, int b); +EAPI void imlib_filter_set_green(int xoff, int yoff, + int a, int r, int g, int b); +EAPI void imlib_filter_set_blue(int xoff, int yoff, + int a, int r, int g, int b); +EAPI void imlib_filter_constants(int a, int r, int g, int b); +EAPI void imlib_filter_divisors(int a, int r, int g, int b); + +EAPI void imlib_apply_filter(char *script, ...); + +EAPI void imlib_image_clear(void); +EAPI void imlib_image_clear_color(int r, int g, int b, int a); + +/* *INDENT-OFF* */ +#ifdef __cplusplus +} +#endif +/* *INDENT-ON* */ +#endif diff --git a/lib/imlib2/libImlib2.so b/lib/imlib2/libImlib2.so new file mode 100644 index 0000000..408710b Binary files /dev/null and b/lib/imlib2/libImlib2.so differ diff --git a/lib/imlib2/libbz2.so b/lib/imlib2/libbz2.so new file mode 100644 index 0000000..4b3ccfe Binary files /dev/null and b/lib/imlib2/libbz2.so differ diff --git a/lib/imlib2/libfreetype.so b/lib/imlib2/libfreetype.so new file mode 100644 index 0000000..0885cba Binary files /dev/null and b/lib/imlib2/libfreetype.so differ diff --git a/lib/imlib2/libpng16.so b/lib/imlib2/libpng16.so new file mode 100644 index 0000000..0230485 Binary files /dev/null and b/lib/imlib2/libpng16.so differ diff --git a/lib/imlib2/libz.so b/lib/imlib2/libz.so new file mode 100644 index 0000000..1ec8401 Binary files /dev/null and b/lib/imlib2/libz.so differ diff --git a/logo.png b/logo.png new file mode 100644 index 0000000..78a3133 Binary files /dev/null and b/logo.png differ diff --git a/menu.cpp b/menu.cpp index c47acba..00c68c8 100644 --- a/menu.cpp +++ b/menu.cpp @@ -804,6 +804,7 @@ void HandleUI(void) case KEY_F12: menu = true; menu_key_set(KEY_F12 | UPSTROKE); + video_fb_enable(0); break; case KEY_F1: if (is_menu_core()) @@ -834,7 +835,6 @@ void HandleUI(void) } break; - //debug case KEY_F9: video_fb_enable(!video_fb_state()); if(video_fb_state() || !is_menu_core()) menustate = MENU_NONE1; diff --git a/video.cpp b/video.cpp index b6c878f..943c4df 100644 --- a/video.cpp +++ b/video.cpp @@ -3,6 +3,8 @@ #include #include #include +#include +#include #include "hardware.h" #include "user_io.h" @@ -14,8 +16,9 @@ #include "input.h" #include "support.h" +#include "lib/imlib2/Imlib2.h" -#define FB_SIZE (1024*1024*8) // 8MB +#define FB_SIZE (1024*1024*8/4) // 8MB #define FB_ADDR (0x20000000 + (32*1024*1024)) // 512mb + 32mb(Core's fb) #define FB_FMT 2 // 0 - 16bit, 1 - 24bit(not supported), 2 - 32bit #define FB_RxB 1 @@ -28,10 +31,13 @@ static int fb_enabled = 0; static int fb_width = 0; +static int fb_width_full = 0; static int fb_height = 0; static int fb_stride = 0; static int fb_num = 0; + static int menu_bg = 0; +static int menu_bgn = 0; struct vmode_t { @@ -304,13 +310,14 @@ static void set_video(vmode_custom_t *v, double Fpix) printf("Fpix=%f\n", v_cur.Fpix); DisableIO(); - if (cfg.fb_size < 1) cfg.fb_size = 1; + if (cfg.fb_size < 1) cfg.fb_size = (v_cur.item[1] < 1000) ? 1 : 2; else if (cfg.fb_size == 3) cfg.fb_size = 2; else if (cfg.fb_size > 4) cfg.fb_size = 4; fb_width = v_cur.item[1] / cfg.fb_size; fb_height = v_cur.item[5] / cfg.fb_size; fb_stride = ((fb_width * (FB_FMT ? 4 : 2)) + 255) & ~255; + fb_width_full = fb_stride / (FB_FMT + 2); if (fb_enabled) video_fb_enable(1, fb_num); @@ -398,11 +405,7 @@ static void fb_init() int fd = open("/dev/mem", O_RDWR | O_SYNC); if (fd == -1) return; -#if(FB_FMT == 2) - fb_base = (volatile uint32_t*)mmap(0, FB_SIZE * 3, PROT_READ | PROT_WRITE, MAP_SHARED, fd, FB_ADDR); -#else - fb_base = (volatile uint16_t*)mmap(0, FB_SIZE * 3, PROT_READ | PROT_WRITE, MAP_SHARED, fd, FB_ADDR); -#endif + fb_base = (volatile uint32_t*)mmap(0, FB_SIZE * 4 * 3, PROT_READ | PROT_WRITE, MAP_SHARED, fd, FB_ADDR); if (fb_base == (void *)-1) { printf("Unable to mmap FB!\n"); @@ -425,7 +428,7 @@ void video_mode_load() static int api1_5 = 0; int hasAPI1_5() { - return api1_5; + return api1_5 || is_menu_core(); } static uint32_t show_video_info(int force) @@ -582,12 +585,12 @@ void video_fb_enable(int enable, int n) if (is_menu_core() && !enable && menu_bg) { enable = 1; - n = 1; + n = menu_bgn; } if (enable) { - uint32_t fb_addr = FB_ADDR + (FB_SIZE*n); + uint32_t fb_addr = FB_ADDR + (FB_SIZE * 4 * n); fb_num = n; printf("Switch to HPS frame buffer\n"); @@ -643,12 +646,12 @@ int video_fb_state() static void draw_checkers() { - volatile uint32_t* buf = fb_base + (FB_SIZE / 4); + volatile uint32_t* buf = fb_base + (FB_SIZE*menu_bgn); int stride = fb_stride / (FB_FMT + 2); - uint32_t col1 = 0xCCCCCC; - uint32_t col2 = 0x888888; - int sz = 16; + uint32_t col1 = 0x888888; + uint32_t col2 = 0x666666; + int sz = fb_width/128; int pos = 0; for (int y = 0; y < fb_height; y++) @@ -665,21 +668,25 @@ static void draw_checkers() static void draw_hbars1() { - volatile uint32_t* buf = fb_base + (FB_SIZE / 4); + volatile uint32_t* buf = fb_base + (FB_SIZE*menu_bgn); int stride = fb_stride / (FB_FMT + 2); int old_base = 0; int gray = 255; + int sz = fb_height/7; + int stp = 0; for (int y = 0; y < fb_height; y++) { int pos = y * stride; - int base_color = 7-((7 * y) / fb_height); + int base_color = ((7 * y) / fb_height)+1; if (old_base != base_color) { - gray = 255; + stp = sz; old_base = base_color; } + gray = 255 * stp / sz; + for (int x = 0; x < fb_width; x++) { uint32_t color = 0; @@ -689,14 +696,14 @@ static void draw_hbars1() buf[pos++] = color; } - gray -= 3; - if (gray < 0) gray = 0; + stp--; + if (stp < 0) stp = 0; } } static void draw_hbars2() { - volatile uint32_t* buf = fb_base + (FB_SIZE / 4); + volatile uint32_t* buf = fb_base + (FB_SIZE*menu_bgn); int stride = fb_stride / (FB_FMT + 2); for (int y = 0; y < fb_height; y++) @@ -721,8 +728,10 @@ static void draw_hbars2() static void draw_vbars1() { - volatile uint32_t* buf = fb_base + (FB_SIZE / 4); + volatile uint32_t* buf = fb_base + (FB_SIZE*menu_bgn); int stride = fb_stride / (FB_FMT + 2); + int sz = fb_width / 7; + int stp = 0; for (int y = 0; y < fb_height; y++) { @@ -731,26 +740,30 @@ static void draw_vbars1() int gray = 255; for (int x = 0; x < fb_width; x++) { - int base_color = 7-((7 * x) / fb_width); + int base_color = ((7 * x) / fb_width)+1; if (old_base != base_color) { - gray = 255; + stp = sz; old_base = base_color; } + + gray = 255 * stp / sz; + uint32_t color = 0; if (base_color & 4) color |= gray; if (base_color & 2) color |= gray << 8; if (base_color & 1) color |= gray << 16; buf[pos++] = color; - gray -= 2; - if (gray < 0) gray = 0; + + stp--; + if (stp < 0) stp = 0; } } } static void draw_vbars2() { - volatile uint32_t* buf = fb_base + (FB_SIZE / 4); + volatile uint32_t* buf = fb_base + (FB_SIZE*menu_bgn); int stride = fb_stride / (FB_FMT + 2); for (int y = 0; y < fb_height; y++) @@ -758,7 +771,7 @@ static void draw_vbars2() int pos = y * stride; for (int x = 0; x < fb_width; x++) { - int gray = 255 - ((256 * y) / fb_height); + int gray = ((256 * y) / fb_height); int base_color = ((14 * x) / fb_width); int inv = base_color & 1; base_color >>= 1; @@ -776,7 +789,7 @@ static void draw_vbars2() static void draw_spectrum() { - volatile uint32_t* buf = fb_base + (FB_SIZE / 4); + volatile uint32_t* buf = fb_base + (FB_SIZE*menu_bgn); int stride = fb_stride / (FB_FMT + 2); for (int y = 0; y < fb_height; y++) @@ -785,8 +798,8 @@ static void draw_spectrum() int blue = ((256 * y) / fb_height); for (int x = 0; x < fb_width; x++) { - int red = ((256 * x) / fb_width) - blue / 2; - int green = 255 - red - blue / 2; + int green = ((256 * x) / fb_width) - blue / 2; + int red = 255 - green - blue / 2; if (red < 0) red = 0; if (green < 0) green = 0; @@ -797,7 +810,7 @@ static void draw_spectrum() static void draw_black() { - volatile uint32_t* buf = fb_base + (FB_SIZE / 4); + volatile uint32_t* buf = fb_base + (FB_SIZE*menu_bgn); int stride = fb_stride / (FB_FMT + 2); for (int y = 0; y < fb_height; y++) @@ -807,33 +820,127 @@ static void draw_black() } } +static uint64_t getus() +{ + struct timeval tv; + gettimeofday(&tv, NULL); + return (tv.tv_sec * 10000000) + tv.tv_usec; +} + +static void vs_wait() +{ + int fb = open("/dev/fb0", O_RDWR); + int zero = 0; + uint64_t t1, t2; + if (ioctl(fb, FBIO_WAITFORVSYNC, &zero) == -1) + { + printf("fb ioctl failed: %s\n", strerror(errno)); + close(fb); + return; + } + + t1 = getus(); + ioctl(fb, FBIO_WAITFORVSYNC, &zero); + t2 = getus(); + close(fb); + + printf("vs_wait(us): %llu\n", t2 - t1); +} + +extern uint8_t _binary_logo_png_start[], _binary_logo_png_end[]; void video_menu_bg(int n) { menu_bg = n; - video_fb_enable(0); - - switch (n) + if (n) { - case 1: - draw_checkers(); - break; - case 2: - draw_hbars1(); - break; - case 3: - draw_hbars2(); - break; - case 4: - draw_vbars1(); - break; - case 5: - draw_vbars2(); - break; - case 6: - draw_spectrum(); - break; - case 7: - draw_black(); - break; + menu_bgn = (menu_bgn == 1) ? 2 : 1; + + static Imlib_Image menubg = 0; + static Imlib_Image bg1 = 0, bg2 = 0; + if (!bg1) bg1 = imlib_create_image_using_data(fb_width_full, fb_height, (uint32_t*)(fb_base + (FB_SIZE * 1))); + if (!bg2) bg2 = imlib_create_image_using_data(fb_width_full, fb_height, (uint32_t*)(fb_base + (FB_SIZE * 2))); + + Imlib_Image *bg = (menu_bgn == 1) ? &bg1 : &bg2; + + switch (n) + { + case 1: + if (menubg || FileExists("menu.png") || FileExists("menu.jpg")) + { + if (!menubg) menubg = imlib_load_image_immediately(getFullPath("menu.png")); + if (!menubg) menubg = imlib_load_image_immediately(getFullPath("menu.jpg")); + if (menubg) + { + imlib_context_set_image(menubg); + int src_w = imlib_image_get_width(); + int src_h = imlib_image_get_height(); + if (*bg) + { + imlib_context_set_image(*bg); + imlib_blend_image_onto_image(menubg, 255, + 0, 0, //int source_x, int source_y, + src_w, src_h, //int source_width, int source_height, + 0, 0, //int destination_x, int destination_y, + fb_width, fb_height //int destination_width, int destination_height + ); + break; + } + } + } + draw_checkers(); + break; + case 2: + draw_hbars1(); + break; + case 3: + draw_hbars2(); + break; + case 4: + draw_vbars1(); + break; + case 5: + draw_vbars2(); + break; + case 6: + draw_spectrum(); + break; + case 7: + draw_black(); + break; + } + + static Imlib_Image logo = 0; + if (!logo) + { + unlink("/tmp/logo.png"); + if (FileSave("/tmp/logo.png", _binary_logo_png_start, _binary_logo_png_end - _binary_logo_png_start, 1)) + { + logo = imlib_load_image_immediately("/tmp/logo.png"); + unlink("/tmp/logo.png"); + } + } + if (logo) + { + imlib_context_set_image(logo); + + int src_w = imlib_image_get_width(); + int src_h = imlib_image_get_height(); + + if (*bg) + { + imlib_context_set_image(*bg); + imlib_blend_image_onto_image(logo, 255, + 0, 0, //int source_x, int source_y, + src_w, src_h, //int source_width, int source_height, + 0, 0, //int destination_x, int destination_y, + fb_width*2 / 7, src_h*fb_width*2 / (src_w * 7) //int destination_width, int destination_height + ); + } + } + + //test the fb driver + vs_wait(); } + + video_fb_enable(0); }