📄 dev_sdl.c
字号:
cur_y += font_h; } else { char *buf; int len; // scroll// gl_copybox(0, font_h, os_graf_mx, cur_y, 0, 0); len = cur_y * bytespp * os_graf_mx; buf = (char *) malloc(len); memcpy(buf, (char*) screen->pixels + font_h*bytespp*os_graf_mx, len); memcpy(screen->pixels, buf, len); free(buf); sdl_fillrect(0, cur_y, os_graf_mx, font_h, cmap[15]); }}/** calc next tab position*/int osd_calctab(int x){ int c = 1; while ( x > tabsize ) { x -= tabsize; c ++; } return c * tabsize;}/*** Basic output** Supported control codes:* \t tab (20 px)* \a beep* \n next line (cr/lf)* \xC clear screen* \e[K clear to end of line* \e[0m reset all attributes to their defaults* \e[1m set bold on* \e[4m set underline on* \e[7m reverse video* \e[21m set bold off* \e[24m set underline off* \e[27m set reverse off*/void osd_write(const char *str){ int len, cx = 8, esc_val, esc_cmd; byte *p, buf[3]; int ch, char_len = 1; len = strlen(str); if ( len <= 0 ) return; SDL_LockSurface(screen); p = (byte *) str; while ( *p ) { switch ( *p ) { case '\a': // beep osd_beep(); break; case '\t': cur_x = osd_calctab(cur_x+1); break; case '\xC': osd_cls(); break; case '\033': // ESC ctrl chars (man console_codes) if ( *(p+1) == '[' ) { p += 2; esc_val = esc_cmd = 0; if ( is_digit(*p) ) { esc_val = (*p - '0'); p ++; if ( is_digit(*p) ) { esc_val = (esc_val * 10) + (*p - '0'); p ++; } esc_cmd = *p; } else esc_cmd = *p; // control characters switch ( esc_cmd ) { case 'K': // \e[K - clear to eol sdl_fillrect(cur_x, cur_y, os_graf_mx - cur_x, cur_y+font_h, cmap[15]); break; case 'm': // \e[...m - ANSI terminal switch ( esc_val ) { case 0: // reset con_use_bold = 0; con_use_ul = 0; con_use_reverse = 0; osd_setcolor(0); osd_settextcolor(0, 15); break; case 1: // set bold on con_use_bold = 1; break; case 4: // set underline on con_use_ul = 1; break; case 7: // reverse video on con_use_reverse = 1; break; case 21: // set bold off con_use_bold = 0; break; case 24: // set underline off con_use_ul = 0; break; case 27: // reverse video off con_use_reverse = 0; break; // colors - 30..37 foreground, 40..47 background case 30: // set black fg osd_setcolor(0); break; case 31: // set red fg osd_setcolor(4); break; case 32: // set green fg osd_setcolor(2); break; case 33: // set brown fg osd_setcolor(6); break; case 34: // set blue fg osd_setcolor(1); break; case 35: // set magenta fg osd_setcolor(5); break; case 36: // set cyan fg osd_setcolor(3); break; case 37: // set white fg osd_setcolor(7); break; case 40: // set black bg osd_settextcolor(cmap[dev_fgcolor], 0); break; case 41: // set red bg osd_settextcolor(cmap[dev_fgcolor], 4); break; case 42: // set green bg osd_settextcolor(cmap[dev_fgcolor], 2); break; case 43: // set brown bg osd_settextcolor(cmap[dev_fgcolor], 6); break; case 44: // set blue bg osd_settextcolor(cmap[dev_fgcolor], 1); break; case 45: // set magenta bg osd_settextcolor(cmap[dev_fgcolor], 5); break; case 46: // set cyan bg osd_settextcolor(cmap[dev_fgcolor], 3); break; case 47: // set white bg osd_settextcolor(cmap[dev_fgcolor], 7); break; }; break; } } break; case '\n': // new line SDL_UnlockSurface(screen); osd_nextln(); SDL_LockSurface(screen); break; case '\r': // return cur_x = 0; sdl_fillrect(cur_x, cur_y, os_graf_mx - cur_x, cur_y+font_h, cmap[15]); break; default: // // PRINT THE CHARACTER // buf[0] = *p; buf[1] = '\0'; // new line ? if ( cur_x + cx >= dev_x2clip ) osd_nextln(); // draw // TODO: ??? SJIS on Linux ??? if ( !con_use_reverse ) { osd_drawchar(cur_x, cur_y, *p, 1, cmap[dev_fgcolor], cmap[dev_bgcolor]); if ( con_use_bold ) osd_drawchar(cur_x-1, cur_y, *p, 0, cmap[dev_fgcolor], cmap[dev_bgcolor]); } else { osd_drawchar(cur_x, cur_y, *p, 1, cmap[dev_bgcolor], cmap[dev_fgcolor]); if ( con_use_bold ) osd_drawchar(cur_x-1, cur_y, *p, 0, cmap[dev_bgcolor], cmap[dev_fgcolor]); } if ( con_use_ul ) { osd_setcolor(dev_fgcolor); sdl_line(cur_x, (cur_y+font_h)-1, cur_x+cx, (cur_y+font_h)-1); } // advance cur_x += cx; }; if ( *p == '\0' ) break; p ++; } SDL_UnlockSurface(screen);// SDL_UpdateRect(screen, 0, 0, 0, 0);}int osd_events(int wait_flag){ int ch, button, upr; int evc = 0; SDL_Event ev; SDL_UpdateRect(screen, 0, 0, 0, 0); if ( wait_flag == 0 ) { if ( SDL_PollEvent(&ev) ) { switch ( ev.type ) { case SDL_KEYDOWN: ch = ev.key.keysym.sym; if ( ch == SDLK_c && (ev.key.keysym.mod & KMOD_CTRL) ) { return -2; } else if ( ch == SDLK_CAPSLOCK ) ; else if ( ch == SDLK_LSHIFT || ch == SDLK_RSHIFT ) ; else if ( ch == SDLK_LALT || ch == SDLK_RALT ) ; else if ( ch == SDLK_LCTRL || ch == SDLK_RCTRL ) ; else if ( ch == SDLK_RETURN ) dev_pushkey('\n'); else if ( ch == SDLK_BACKSPACE ) dev_pushkey(8); else if ( ch == 127 ) dev_pushkey(8); else { upr = ( ((ev.key.keysym.mod & (KMOD_CAPS))) && ((ev.key.keysym.mod & (KMOD_SHIFT)) == 0) ) || ( ((ev.key.keysym.mod & (KMOD_CAPS)) == 0) && ((ev.key.keysym.mod & KMOD_SHIFT)) ); if ( upr ) dev_pushkey(toupper(ch)); else dev_pushkey(ch); } evc ++; break; case SDL_MOUSEBUTTONDOWN: case SDL_MOUSEBUTTONUP: case SDL_MOUSEMOTION: button = SDL_GetMouseState(&mouse_x, &mouse_y); if ( mouse_x < mouse_hot_x ) mouse_x = mouse_hot_x; if ( mouse_y < mouse_hot_y ) mouse_y = mouse_hot_y; if ( mouse_x >= os_graf_mx - 1 ) mouse_x = os_graf_mx - 1; if ( mouse_y >= os_graf_my - 1 ) mouse_y = os_graf_my - 1;// vga_setcursorposition(mouse_x + mouse_hot_x, mouse_y + mouse_hot_y); mouse_b = 0; /// bug if ( button & SDL_BUTTON(1) ) { if ( (mouse_b & SDL_BUTTON(1)) == 0 ) { // new press mouse_down_x = mouse_x; mouse_down_y = mouse_y; } mouse_upd = 1; mouse_pc_x = mouse_x; mouse_pc_y = mouse_y; mouse_b |= 1; } if (button & SDL_BUTTON(2)) mouse_b |= 2; if (button & SDL_BUTTON(3)) mouse_b |= 4; evc ++; } } } else { while ( (evc = osd_events(0)) == 0 ) SDL_Delay(50); } return evc;}///////////////////////////////////////////////////////////////void osd_setcolor(int color){ dev_fgcolor = color;}void osd_line(int x1, int y1, int x2, int y2){ SDL_LockSurface(screen); if ( (x1 == x2) && (y1 == y2) ) sdl_setpixel(x1, y1, cmap[dev_fgcolor]); else sdl_line(x1, y1, x2, y2); SDL_UnlockSurface(screen);// SDL_UpdateRect(screen, 0, 0, 0, 0);}void osd_setpixel(int x, int y){ SDL_LockSurface(screen); sdl_setpixel(x, y, cmap[dev_fgcolor]); SDL_UnlockSurface(screen);// SDL_UpdateRect(screen, 0, 0, 0, 0);}void osd_rect(int x1, int y1, int x2, int y2, int fill){ int y; SDL_LockSurface(screen); if ( fill ) { for ( y = y1; y <= y2; y ++ ) sdl_line(x1, y, x2, y); } else { sdl_line(x1, y1, x2, y2); sdl_line(x1, y1, x1, y2); sdl_line(x1, y2, x2, y2); sdl_line(x2, y2, x2, y1); sdl_line(x2, y1, x1, y1); } SDL_UnlockSurface(screen);// SDL_UpdateRect(screen, 0, 0, 0, 0);}///////////////////////////////////////////////////////////////void osd_sound(int freq, int ms, int vol, int bgplay){ struct voice_info *info; int i, loops; if ( has_audio ) { if ( !freq ) freq = audiospec.freq / 2; loops = ((ms * audiospec.freq / freq / 2.0) / audiospec.samples) / 1000; SDL_LockAudio(); info = &audio_info[audio_tail]; info->vol = vol; info->setting = 0; info->period = 0; info->toggle = 1; if ( (freq < audiospec.freq / 2) && (freq != 0) ) { info->period = (float) (audiospec.freq / freq / 2.0); info->setting = (info->setting > 0) ? info->vol : -info->vol; } else info->period = 0.0; // audio_tail ++; if ( audio_tail >= AUDIO_STACK_MAX ) audio_tail = 0; for ( i = 1; i < loops; i ++ ) { audio_info[audio_tail] = *info; audio_info[audio_tail].toggle = 0; audio_tail ++; if ( audio_tail >= AUDIO_STACK_MAX ) audio_tail = 0; } SDL_UnlockAudio(); if ( !bgplay ) SDL_Delay(ms); }}void osd_beep(){ if ( has_audio ) osd_sound(440, 250, 75, 0); else printf("\a");}///////////////////////////////////////////////////////////////int osd_textwidth(const char *str){ int l = strlen(str); // SJIS ??? return l * 8;}int osd_textheight(const char *str){ // TODO: count \n return font_h;}#if defined(TAKE_SCREENSHOT)//void writeppm(char *name){ int y, i, j, k; FILE *file; byte *tmp, *tmp2; int width = os_graf_mx; int height = os_graf_my; int bpp = os_color_depth; file = fopen(name, "wt"); fprintf(file, "P6\n%i %i\n255\n", width, height); tmp = (byte *) malloc(width*4); tmp2 = (byte *) malloc(width*4); for ( y = 0; y < height; y++ ) { memcpy(tmp, screen->pixels+(screen->w*y*bytespp), width * bytespp); switch ( bpp ) { case 16: for ( i = 0; i < width; i++ ) { j = tmp[i * 2] + 256 * tmp[i * 2 + 1]; tmp2[i * 3] = (j & 0xf800) >> 8; tmp2[i * 3 + 1] = (j & 0x7e0) >> 3; tmp2[i * 3 + 2] = (j & 0x1f) << 3; } break; case 24: case 32: memcpy(tmp2, tmp, width * 3); break; } fwrite(tmp2, width * 3, 1, file); } free(tmp); free(tmp2); fclose(file);}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -