?? display_ascii.c
字號:
/* * * Copyright (c) Sigma Designs, Inc. 2002. All rights reserved. * *//** * @file osdbuf_control.c * @brief application to use fonts with OSD buffers * * @author Pascal Cannenterre */#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <time.h>#include <sys/stat.h>#include <sys/mman.h>#include <getopt.h>#define ALLOW_OS_CODE 1#include "../dcc/include/dcc.h"#include "common.h"#include "osdlib.h"#include "../rmcore/include/rmcore.h"/* For debug/verbose output */#if 0#define DEB(f) (f)#else#define DEB(f)#endif#define DEFAULT_OSD_WIDTH 640#define DEFAULT_OSD_HEIGHT 480#define DEFAULT_OSD_BPP 32#define DEFAULT_DRAM 0#define DEFAULT_OSD_FORMAT OSD_FORMAT_TC#define DEFAULT_OSD_SUBFORMAT OSD_SUBFORMAT_32BPP#define DEFAULT_CHIP 0typedef struct { RMuint8 *data; RMint32 width; RMint32 height; RMint32 numchars; RMint32 version; RMint32 flags; RMint32 size;} psf_font;typedef struct { psf_font *font; RMuint32 x,y; RMuint8 scale; RMuint32 wanted_height; RMuint32 fg, bg; RMascii *text;} osd_display_ascii_type;/* Global */static int xpos, ypos, refresh, scale, direction;static char fg_R, fg_G, fg_B, fg_A;static char bg_R, bg_G, bg_B, bg_A;static char create_osd = 0;static psf_font *font = NULL;static RMuint8 *osd_base_addr; //Base address where OSD is mapped// static RMuint32 DisplayProfileCachedAddr = 0, DisplayProfileUncachedAddr = 0;static struct osd_descriptor p_osd;static RMuint32 get_int(RMuint8 *p) { RMuint32 i, res; res = 0; for (i=0 ; i<4 ; i++) { res += p[i] << (8*i); } return res;}static psf_font *osd_load_ps_font(RMuint8 *font_buf){ psf_font *font; RMuint32 headersize = 0; font=(psf_font *) malloc(sizeof(psf_font)); if ((font_buf[0] == 0x36) && (font_buf[1] == 0x04)) { font->flags = font_buf[2]; font->height = font_buf[3]; font->width = 8; if (font->flags & 0x01) font->numchars = 512; else font->numchars = 256; font->size = font->height; headersize = 4; } else { if ((font_buf[0] == 0x72) && (font_buf[1] == 0xb5) && (font_buf[2] == 0x4a) && (font_buf[3] = 0x86)){ font->version = get_int(font_buf + 4); headersize = get_int(font_buf + 8); font->flags = get_int(font_buf + 12); font->numchars = get_int(font_buf + 16); font->size = get_int(font_buf + 20); font->height = get_int(font_buf + 24); font->width = get_int(font_buf + 28); } } font->data = calloc(font->numchars*font->size,sizeof(RMuint8)); memcpy(font->data, font_buf + headersize, font->numchars*font->size); return font;}static void osd_unload_ps_font(psf_font *font){ if (font == NULL) return; free(font->data); free(font);}static void osd_write_ascii(struct osd_descriptor *m_osd,RMuint8 *base_addr, osd_display_ascii_type *val){ RMuint32 len=strlen(val->text); RMint32 y,x,yy,xx,k,l,i; RMuint32 color; RMuint8 *p; /* for (y=0 ; y < val->font->height * val->scale ; y ++) for (x=0 ; x < len * (val->font->width + 1) * val->scale ; x ++) OSD_SetPixel(pOsd,pDim,val->x+x,val->y+y,val->bg);*/ x = val->x; y = val->y; for(i=0;i<(RMint32)len;i++) { if (val->text[i]<32) break; p = val->font->data + (val->text[i] * val->font->size); for (yy=0 ; yy<val->font->height ; yy++) { for (xx=0 ; xx<val->font->width ; xx++) { if (*p & (1 << (7 - (xx%8)))){ color = (RMuint32) val->fg; }else color = (RMuint32) val->bg; for (k=0 ; k<val->scale ; k++) for (l=0 ; l<val->scale ; l++) osdbuf_set_pixel(m_osd, base_addr, x+(xx*val->scale)+l, y+(yy*val->scale)+k, color); if (xx%8 == 7) p++; } if ((val->font->width % 8) != 0) p++; } x += (val->font->width + 1) * val->scale; }}/* Load VGA font... Used in my game TB1 *//* psf font support added by <bkbratko@ardu.raaf.defence.gov.au> */static psf_font *load_psf_font(char *namest){ FILE *f; struct stat buf; RMuint32 size; RMuint8 *font_buf; psf_font *font; f=fopen(namest,"r"); if (f==NULL) { printf("ERROR loading font file %s.\n",namest); return NULL; } stat("font.psf",&buf); size=buf.st_size; font_buf = (RMuint8 *) malloc(size); fread(font_buf, 1, size, f); font = osd_load_ps_font(font_buf); free(font_buf); fclose(f); return font;}static int parse_command_line(int argc, char **argv){ int i; xpos = ypos = refresh = 0; scale = 1; direction = 1; fg_A = bg_A = 255; // no transparency by default fg_R = fg_G = fg_B = 255; bg_R = bg_G = bg_B = 0; /* starts at 2 because first argument is the board number ....*/ for(i=2;i<argc;i++) { if ((argv[i][0]=='-')) { switch(argv[i][1]) { case 'X': i++; xpos = atoi(argv[i]); break; case 'Y': i++; ypos = atoi(argv[i]); break; case 'T': i++; refresh = atoi(argv[i]); break; case 'S': i++; scale = atoi(argv[i]); break; case 'D': i++; direction = atoi(argv[i]); break; case 'F': i++; sscanf(argv[i], "%hhu,%hhu,%hhu,%hhu", &fg_R, &fg_G, &fg_B, &fg_A); break; case 'B': i++; sscanf(argv[i], "%hhu,%hhu,%hhu,%hhu", &bg_R, &bg_G, &bg_B, &bg_A); break; case 'N': create_osd = 1; break; default: return 0; } } else break; } return i;}static void init_lut(struct osd_descriptor *m_osd, RMuint8 *base_addr, osd_display_ascii_type *disp){ memset((void *)disp, 0, sizeof(osd_display_ascii_type)); DEB(fprintf(stderr,"init_lut, bpp = %ld\n", m_osd->bpp)); set_osdbuf_palette(m_osd, 0, bg_R, bg_G, bg_B, bg_A); set_osdbuf_palette(m_osd, 1, fg_R, fg_G, fg_B, fg_A); disp->bg = 0; disp->fg = 1; { int x,y; for (x=0;x<(int)m_osd->profile.Width;x++) for (y=0;y<(int)m_osd->profile.Height;y++) osdbuf_set_pixel(m_osd,base_addr,x,y,0); } // make two colored rectangles to show how to access osdbuf pixel { int x,y; for (x=20;x<150;x++) for (y=180;y<290;y++) osdbuf_set_pixel(m_osd,base_addr,x,y,1); // index 1 is fg color for (x=100;x<200;x++) for (y=220;y<330;y++) osdbuf_set_pixel(m_osd,base_addr,x,y,0); // index 0 is bg color }}static void init_tc(struct osd_descriptor *m_osd, RMuint8 *base_addr, osd_display_ascii_type *disp){ RMuint32 bg_color = 0 , fg_color = 0; memset((void *)disp, 0, sizeof(osd_display_ascii_type)); bg_color = 0; fg_color = 0; switch(m_osd->profile.ColorFormat){ case EMhwlibColorFormat_24BPP_565 : case EMhwlibColorFormat_24BPP : case EMhwlibColorFormat_32BPP_4444: case EMhwlibColorFormat_32BPP : /* for 24BPP, alpha will not be taken */ RMinsShiftBits(&bg_color, bg_A, 8, 24); RMinsShiftBits(&bg_color, bg_R, 8, 16); RMinsShiftBits(&bg_color, bg_G, 8, 8); RMinsShiftBits(&bg_color, bg_B, 8, 0); RMinsShiftBits(&fg_color, fg_A, 8, 24); RMinsShiftBits(&fg_color, fg_R, 8, 16); RMinsShiftBits(&fg_color, fg_G, 8, 8); RMinsShiftBits(&fg_color, fg_B, 8, 0); break; case EMhwlibColorFormat_16BPP_565: RMinsShiftBits(&bg_color, bg_R, 5, 11); RMinsShiftBits(&bg_color, bg_G, 6, 5); RMinsShiftBits(&bg_color, bg_B, 5, 0); RMinsShiftBits(&fg_color, fg_R, 5, 11); RMinsShiftBits(&fg_color, fg_G, 6, 5); RMinsShiftBits(&fg_color, fg_B, 5, 0); break; case EMhwlibColorFormat_16BPP_1555: RMinsShiftBits(&bg_color, bg_A, 1, 15); RMinsShiftBits(&bg_color, bg_R, 5, 10); RMinsShiftBits(&bg_color, bg_G, 5, 5); RMinsShiftBits(&bg_color, bg_B, 5, 0); RMinsShiftBits(&fg_color, fg_A, 1, 15); RMinsShiftBits(&fg_color, fg_R, 5, 10); RMinsShiftBits(&fg_color, fg_G, 5, 5); RMinsShiftBits(&fg_color, fg_B, 5, 0); break; case EMhwlibColorFormat_16BPP_4444: RMinsShiftBits(&bg_color, bg_A, 4, 12); RMinsShiftBits(&bg_color, bg_R, 4, 8); RMinsShiftBits(&bg_color, bg_G, 4, 4); RMinsShiftBits(&bg_color, bg_B, 4, 0); RMinsShiftBits(&fg_color, fg_A, 4, 12); RMinsShiftBits(&fg_color, fg_R, 4, 8); RMinsShiftBits(&fg_color, fg_G, 4, 4); RMinsShiftBits(&fg_color, fg_B, 4, 0); break; } disp->fg = fg_color; disp->bg = bg_color; DEB(fprintf(stderr,"bg color = 0x%08lx, fg color = 0x%08lx\n", bg_color, fg_color)); { int x,y; for (x=0;x<(int)m_osd->profile.Width;x++) for (y=0;y<(int)m_osd->profile.Height;y++) osdbuf_set_pixel(m_osd,base_addr,x,y,bg_color); } // make two colored rectangles to show how to access osdbuf pixel { int x,y; for (x=20;x<150;x++) for (y=180;y<290;y++) osdbuf_set_pixel(m_osd,base_addr,x,y,fg_color); // index 1 is fg color for (x=100;x<200;x++) for (y=220;y<330;y++) osdbuf_set_pixel(m_osd,base_addr,x,y,bg_color); // index 2 is bg color }}/** Cleanup */static void cleanup(void *param){ RMstatus err; struct osd_descriptor *my_osd=(struct osd_descriptor *)param; DEB(fprintf(stderr,"begin cleanup\n")); if (my_osd == NULL) return; if(my_osd->dcc_info.pRUA) { (void)RUAUnMap(my_osd->dcc_info.pRUA, osd_base_addr, p_osd.LumaSize); (void)RUAUnLock(my_osd->dcc_info.pRUA, p_osd.LumaAddr, p_osd.LumaSize); } if (create_osd){ // del_current_osdbuf(p_rua); } osd_unload_ps_font(font); if (my_osd->dcc_info.pDCC){ err = DCCClose(my_osd->dcc_info.pDCC); if (RMFAILED(err)) fprintf(stderr, "Cannot close DCC %d\n", err); } if (my_osd->dcc_info.pRUA){ err = RUADestroyInstance(my_osd->dcc_info.pRUA); if (RMFAILED(err)) fprintf(stderr, "Cannot destroy RUA instance %d\n", err); } DEB(fprintf(stderr,"end cleanup\n"));}int main(int argc, char **argv){ // struct display_param dp1, dp2; int no = 0; char font_name[255]; char text[255]; int i; int text_is_present; time_t t; RMstatus status; osd_display_ascii_type disp; struct display_context disp_info; p_osd.dcc_info.disp_info = &disp_info; /* Catch all temination signals, call RMTermInit() and cleanup(), then exit(0). */ RMSignalInit(cleanup, &p_osd); // get_display_param(&argc, argv, &dp1, &dp2); text[0] = '\0'; text_is_present = 0; if ((argc<3) || ((i = parse_command_line(argc, argv)) == 0)) { fprintf(stderr, "Usage: %s <board number> [-F col] [-B col] [-X xpos] [-Y ypos] [-N] [-T sec] [-S scale] <font file> [ascii text]\n" "\t-X : x coordinate of the text\n" "\t-Y : y coordinate of the text\n" "\t-T : refresh every sec seconds. 0 means no refresh\n" "\t-S : scale factor of the font\n" "\t-D : direction : 1 left -> right [default]\n" "\t-D : : 2 down -> up\n" "\t-D : : 3 right-> left\n" "\t-D : : 4 up -> down\n" "\t-F : foreground color\n" "\t-B : background color\n" "\tcolor is formatted as : R,G,B,alpha\n" "\n" "Examples\n" "\t%s 0 -X 300 -Y 200 -S 2 -F 255,0,0,255 -B 0,0,255,128 font.psf \"foo bar\"\n" "\t%s 0 -X 300 -Y 200 -S 1 -F 255,0,0,255 -B 0,0,255,128 -T 1 font.psf\n" ,argv[0],argv[0],argv[0]); // fprintf(stderr,"\nIf you specify -N, then you can also add display options after the board number :\n" DISPLAY_LONG_HELP); return EXIT_FAILURE; } if (create_osd){ } no = atoi(argv[1]); strcpy(font_name,argv[i]); i++; if (i < argc) { strcpy(text, argv[i]); text_is_present = 1; } font=load_psf_font(font_name); if (font==NULL) return(EXIT_FAILURE); DEB(fprintf(stderr," RUACreateInstance\n")); p_osd.chip_num = no; status = RUACreateInstance(&(p_osd.dcc_info.pRUA),p_osd.chip_num); if(RMFAILED(status)) { printf("Error creating intance : %d\n",status); goto wayout; } DEB(fprintf(stderr," DCCOpen\n")); status = DCCOpen(p_osd.dcc_info.pRUA, &(p_osd.dcc_info.pDCC)); if(RMFAILED(status)) { printf("Error opening DCC : %d\n",status); goto wayout; } if (create_osd){ } status = get_osd_infos(&p_osd); if (RMFAILED(status)) { fprintf(stderr,"Error getting OSD infos : %s\n", RMstatusToString(status)); goto wayout; } if ( p_osd.LumaAddr == 0 || p_osd.LumaSize == 0){ fprintf(stderr,"No OSD buffer currently opened, you should create one with osdbuf_control.\n"); goto wayout; } DEB(fprintf(stderr,"Locking %d bytes of RUA memory ...\n", (int)p_osd.LumaSize)); status = RUALock(p_osd.dcc_info.pRUA, p_osd.LumaAddr, p_osd.LumaSize); if (RMFAILED(status)){ fprintf(stderr,"Error locking OSD buffer at 0x%08lx (%ld bytes): %s\n", p_osd.LumaAddr, p_osd.LumaSize, RMstatusToString(status)); goto wayout; } osd_base_addr = RUAMap(p_osd.dcc_info.pRUA, p_osd.LumaAddr, p_osd.LumaSize); if (osd_base_addr == NULL){ status= RM_ERROR; fprintf(stderr,"Error mapping OSD buffer.\n"); goto wayout; } if (p_osd.profile.ColorMode <= EMhwlibColorMode_LUT_8BPP){ DEB(fprintf(stderr,"test_display_lut\n")); init_lut(&p_osd, osd_base_addr, &disp); } else { DEB(fprintf(stderr,"test_display_tc\n")); init_tc(&p_osd, osd_base_addr, &disp); } if (text_is_present == 0) { time(&t); strcpy(text, ctime(&t)); DEB(fprintf(stderr,"No text, using time : %s", text)); } do { disp.font = font; disp.x = xpos; disp.y = ypos; disp.scale = scale; disp.text = text; if (text_is_present == 0) { time(&t); strcpy(text, ctime(&t)); } osd_write_ascii(&p_osd,osd_base_addr,&disp); sleep(refresh); } while (refresh > 0); (void)RMGetKey();wayout: cleanup(&p_osd); if (RMFAILED(status)) return EXIT_FAILURE; return EXIT_SUCCESS;}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -