📄 simple_text.c
字号:
#include "io.h"#include "simple_graphics.h"/******************************************************************* Function: vid_print_string_alpha** Purpose: Prints a string to the specified location of the screen* using the specified font and color.* Calls vid_print_char_alpha** The color formats are as follows:* 16 bit - R(5):G(6):B(5) (packed)* 24 bit - R(8):G(8):B(8) (packed)* 32 bit - 0 : R(8):G(8):B(8) (unpacked)******************************************************************/int vid_print_string_alpha(int horiz_offset, int vert_offset, int color, int background_color, struct abc_font_struct font[], alt_video_display * display, char string[]){ int i = 0; int tab; int original_horiz_offset; original_horiz_offset = horiz_offset; // Print until we hit the '\0' char. while (string[i]) { //Handle newline char here. if (string[i] == '\n') { horiz_offset = original_horiz_offset; vert_offset += font['|' - 33].bounds_height; // we'll use "|" to add the line to line spacing i++; continue; } // Lay down that character and increment our offsets. if(string[i] == 32) // this is a space in ASCII { if(background_color != CLEAR_BACKGROUND) // need to fill in this spot (setting foreground to background color so that it looks like a drawn in box) { vid_print_char_alpha (horiz_offset, vert_offset, background_color, '-', background_color, font, display); } horiz_offset += font[45 - 33].bounds_width; // using the width of the '-' character for the space width since it's not present in the font } else if(string[i] == '\t') // this is a tab { for( tab = 0; tab < TAB_SPACING; tab++ ) { if(background_color != CLEAR_BACKGROUND) // need to fill in this spot (setting foreground to background color so that it looks like a drawn in box) { vid_print_char_alpha (horiz_offset, vert_offset, background_color, '-', background_color, font, display); } horiz_offset += font[45 - 33].bounds_width; // using the width of the '-' character for the space width since it's not present in the font } } else { vid_print_char_alpha (horiz_offset, vert_offset, color, string[i], background_color, font, display); horiz_offset += font[string[i] - 33].bounds_width; } i++; } return (0);}/******************************************************************* Function: seperate_colour_channels* * Author: JCJB** Purpose: Takes a single colour pointer and break the value into* seperate channels. It supports 16/24(packed/unpacked)* formats as inputs. The results are passed back by* the function working on pointers.*******************************************************************/__inline__ int seperate_color_channels(int color_depth, unsigned char * color, unsigned char * red, unsigned char * green, unsigned char * blue){ int return_value; // error checking in case anyone is listening unsigned short temp_color = 0; if (color_depth == 16) // R(5):G(6):B(5) { temp_color = *color++; // get the first half of the 16 bit color temp_color += (*color << 8); // get the second half of the 16 bit color *blue = temp_color & 0x1F; *green = (temp_color >> 5) & 0x3F; *red = (temp_color >> 11) & 0x1F; return_value = 1; } else if ((color_depth == 24) || (color_depth == 32)) // R(8):G(8):B(8) packed/unpacked { *blue = *color++; *green = *color++; *red = *color; return_value = 1; } else // not a valid color depth for this function { *red = 0; *green = 0; *blue = 0; return_value = 0; } return return_value;}/******************************************************************* Function: merge_color_channels* * Author: JCJB** Purpose: Takes the seperate RGB channels and merges them into* a single 16/24/32 bit location. The caller must* use an unsigned char * pointer to the destination* color allowing the same function to be used for* different color formats and packing.*******************************************************************/__inline__ int merge_color_channels(int color_depth, unsigned char red, unsigned char green, unsigned char blue, unsigned char * color){ int return_value; // error checking in case anyone is listening unsigned short temp_color; if (color_depth == 16) // R(5):G(6):B(5) { temp_color = (blue & 0x1F) | ((green & 0x3F) << 5) | ((red & 0x1F) << 11); // 16 bit color format *color++ = temp_color & 0xFF; *color = (temp_color >> 8) & 0xFF; return_value = 1; } else if ((color_depth == 24) || (color_depth == 32)) // R(8):G(8):B(8) packed/unpacked { *color++ = blue; *color++ = green; *color = red; return_value = 1; } else // not a valid color depth for this function { *color++ = 0; *color++ = 0; *color = 0; return_value = 0; } return return_value; }/******************************************************************* Function: read_from_frame* * Author: JCJB** Purpose: Reads a pixel value from an existing frame buffer and* separates the color channels. This is useful for alpha* blending where the previously rendored pixel value is* needed to calculate the new one.*******************************************************************/__inline__ int read_from_frame (int horiz, int vert, unsigned char *red, unsigned char *green, unsigned char *blue, alt_video_display * display){ int return_value; // error checking in case anyone is listening unsigned int temp_color; unsigned int addr; if( display->color_depth == 32 ) { addr = ((unsigned int)display->buffer_ptrs[display->buffer_being_written]->buffer) + ((unsigned int)((vert * display->width * 4) + (horiz * 4))); temp_color = IORD_32DIRECT(addr, 0); *blue = (unsigned char)(temp_color & 0xFF); *green = (unsigned char)((temp_color >> 8) & 0xFF); *red = (unsigned char)((temp_color >> 16) & 0xFF); return_value = 1; } else if( display->color_depth == 24 ) { addr = ((unsigned int)display->buffer_ptrs[display->buffer_being_written]->buffer) + ((unsigned int)((vert * display->width * 3) + (horiz * 3))); *blue = IORD_8DIRECT(addr, 0); *green = IORD_8DIRECT(addr, 1); *red = IORD_8DIRECT(addr, 2); return_value = 1; } else if( display->color_depth == 16 ) { addr = ((unsigned int)display->buffer_ptrs[display->buffer_being_written]->buffer) + ((unsigned int)((vert * display->width * 2) + (horiz * 2))); temp_color = (unsigned int)IORD_16DIRECT(addr, 0); *blue = (unsigned char)(temp_color & 0x1F); *green = (unsigned char)((temp_color >> 5) & 0x3F); *red = (unsigned char)((temp_color >> 11) & 0x1F); return_value = 1; } else { *blue = 0; *red = 0; *green = 0; return_value = 0; } return return_value;}/******************************************************************* Function: alpha_blending** Purpose: Takes in the alpha value (0-255) and uses that to mix* the font color with the background color.*******************************************************************/__inline__ int alpha_blending (int horiz_offset, int vert_offset, int background_color, unsigned char alpha, unsigned char *red, unsigned char *green, unsigned char *blue, alt_video_display * display){ int return_value; unsigned char background_red, background_green, background_blue; unsigned int blended_red, blended_green, blended_blue; // short since there may be overflow to be clipped // set red, green, and blue of the background color if(background_color == CLEAR_BACKGROUND) { read_from_frame (horiz_offset, vert_offset, &background_red, &background_green, &background_blue, display); } else { seperate_color_channels(display->color_depth, (unsigned char *)&background_color, &background_red, &background_green, &background_blue); } // these blended colors may need to be clipped to the maximum amounts the color depth supports blended_red = (((*red) * alpha) + (background_red * (255 - alpha)))/255; blended_green = (((*green) * alpha) + (background_green * (255 - alpha)))/255; blended_blue = (((*blue) * alpha) + (background_blue * (255 - alpha)))/255; if(display->color_depth == 16) { *red = (blended_red > 0x1F)? 0x1F: blended_red; *green = (blended_green > 0x3F)? 0x3F: blended_green; *blue = (blended_blue > 0x1F)? 0x1F: blended_blue; return_value = 1; } else if((display->color_depth == 24) || (display->color_depth == 32)) { *red = (blended_red > 0xFF)? 0xFF: blended_red; *green = (blended_green > 0xFF)? 0xFF: blended_green; *blue = (blended_blue > 0xFF)? 0xFF: blended_blue; return_value = 1; } else { return_value = 0; } return return_value;} /******************************************************************* Function: vid_print_char_alpha** Purpose: Prints a character to the specified location of the* screen using the specified font and color.*******************************************************************/int vid_print_char_alpha (int horiz_offset, int vert_offset, int color, char character, int background_color, struct abc_font_struct font[], alt_video_display * display){ int i, j; unsigned char * alpha; unsigned char original_red, original_blue, original_green; unsigned char red, green, blue; int new_color; // Assign the pointer of the font bitmap alpha = font[character-33].char_alpha_map; // set red, green, and blue of the font color seperate_color_channels(display->color_depth, (char *)&color, &original_red, &original_green, &original_blue); for(i = 0; i < font[character-33].bounds_height; i++) { for (j = 0; j < font[character-33].bounds_width; j++) { red = original_red; green = original_green; blue = original_blue; // send in the font alpha channel and the colour channels for the blending to occur alpha_blending ((horiz_offset + j), (vert_offset + i), background_color, *alpha, &red, &green, &blue, display); // take the blended pixel and merge the color channels back into a single pixel value merge_color_channels(display->color_depth, red, green, blue, (char *)&new_color); // write the new pixel value out to memory overwriting the current background vid_set_pixel((horiz_offset + j), (vert_offset + i), new_color, display); alpha++; } } return(0);}/******************************************************************* Function: vid_string_pixel_length_alpha** Purpose: Gets the length in pixels of a string in the specified* font. Useful for centering text, and determining the* appropriate size of a text box or button.*******************************************************************/int vid_string_pixel_length_alpha( struct abc_font_struct font[], char string[] ){ int i = 0; int length = 0; // Count the length of the string for( i = 0; string[i] != '\0'; i++ ) { if( string[i] == ' ' ) { // Here we just add the length of the '-' character length += font[45 - 33].bounds_width; } else { length += font[string[i] - 33].bounds_width; } } return( length );}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -