📄 dev_sdl.c
字号:
/** SmallBASIC platform driver for Unix|Win32 + SDL** ndc: 2001-03-03*/#include "device.h"#include "osd.h"#include "str.h"#include <stdio.h>#include <sys/types.h>#include <sys/stat.h>#if defined(_UnixOS)#include <unistd.h>#endif#include <SDL/SDL.h>static int cur_x = 0;static int cur_y = 0;static int bytespp = 1;static int mouse_mode, mouse_x, mouse_y, mouse_b, mouse_upd, mouse_down_x, mouse_down_y, mouse_pc_x, mouse_pc_y;static int tabsize = 32; // from dev_palmstatic int maxline;static int font_h = 16;static int con_use_bold = 0;static int con_use_ul = 0;static int con_use_reverse = 0;// VGA16 colors in RGBstatic unsigned long vga16[] ={0x0, 0x7F, 0x7F00, 0x7F7F, 0x7F0000, 0x7F007F, 0x7F7F00, 0x808080,0x555555, 0xFF, 0xFF00, 0xFFFF, 0xFF0000, 0xFF00FF, 0xFFFF00, 0xFFFFFF };static int cmap[16];// fonts#include "unix/rom16.c"static SDL_Surface *screen;static int has_audio = 0;static int mouse_hot_x = -16, mouse_hot_y = -16;static SDL_AudioSpec audiospec;//#define TAKE_SCREENSHOT#if defined(TAKE_SCREENSHOT)void writeppm(char *name);#endifstruct voice_info { float period; float toggle; int setting; int vol; };static char* mixbuf;#define AUDIO_STACK_MAX 8192*2static struct voice_info audio_info[AUDIO_STACK_MAX];static int audio_head = 0;static int audio_tail = 0;/** I know nothing about sound.* someone to fix it*/void audio_callback(void *user, unsigned char* stream, int length){ int volume; int mix = 0; struct voice_info *info; memset(mixbuf, audiospec.silence, length); if ( audio_head != audio_tail ) { info = &audio_info[audio_head]; volume = (info->vol * SDL_MIX_MAXVOLUME) / 100; if ( info->period >= 1.0 ) { int left = length, j = 0; int count; mix = 1; do { count = (info->toggle < left) ? (int) info->toggle : left; left -= count; info->toggle -= count; while ( count -- ) mixbuf[j++] += info->setting; if ( info->toggle < 1.0 ) { info->toggle += info->period; info->setting = -info->setting; } } while ( left > 0 ); } audio_head ++; if ( audio_head >= AUDIO_STACK_MAX ) audio_head = 0; if ( mix ) SDL_MixAudio(stream, mixbuf, length, volume); }}/** SDL: Initialization*/int osd_devinit(){ SDL_Color colors[256]; int i; if ( SDL_Init(SDL_INIT_VIDEO) < 0 ) { fprintf(stderr, "SDL: Couldn't initialize SDL: %s\n", SDL_GetError()); return 0; } if ( ( screen = SDL_SetVideoMode(640, 480, 16, 0) ) == NULL ) { fprintf(stderr, "SDL: Couldn't set 640x480 video mode: %s\n", SDL_GetError()); return 0; } has_audio = (SDL_InitSubSystem(SDL_INIT_AUDIO) >= 0); os_graf_mx = screen->w; os_graf_my = screen->h; maxline = os_graf_my / font_h; os_graphics = DEVDRV_SDL; os_color_depth = screen->format->BitsPerPixel; os_color = 1; if ( os_color_depth != 8 && os_color_depth != 16 && os_color_depth != 32 ) { fprintf(stderr, "SDL: Couldn't set 640x480 video mode\n"); return 0; } SDL_WM_SetCaption("SmallBASIC/SDL", NULL); bytespp = screen->format->BytesPerPixel; if ( os_color_depth == 8 ) { for ( i = 0; i < 256; i ++) { colors[i].r=i; colors[i].g=i; colors[i].b=i; } for ( i = 0; i < 16; i ++) { colors[i].r=(vga16[i] & 0xFF0000) >> 16; colors[i].g=(vga16[i] & 0xFF00) >> 8; colors[i].b=(vga16[i] & 0xFF); cmap[i] = i; } SDL_SetColors(screen, colors, 0, 256); } else { for ( i = 0; i < 16; i ++ ) { cmap[i] = SDL_MapRGB(screen->format, (vga16[i] & 0xFF0000) >> 16, (vga16[i] & 0xFF00) >> 8, (vga16[i] & 0xFF) ); } } if ( has_audio ) { SDL_AudioSpec wanted; memset(&wanted, 0, sizeof(SDL_AudioSpec)); // Set the audio format wanted.freq = 44100; wanted.format = AUDIO_U8; wanted.channels = 1; wanted.samples = 4096; wanted.callback = audio_callback; wanted.userdata = NULL; // Open the audio device, forcing the desired format if ( SDL_OpenAudio ( &wanted, &audiospec ) < 0 ) has_audio = 0; else { mixbuf = (char *) malloc(0x10000); SDL_PauseAudio(0); } } #if defined(_UnixOS) setsysvar_str(SYSVAR_OSNAME, "Unix/SDL"); #else setsysvar_str(SYSVAR_OSNAME, "Win32/SDL"); #endif osd_cls(); return 1;}/** close*/int osd_devrestore(){ cur_x = 0; cur_y = (maxline - 1) * font_h; osd_write("SDL: Press any key to exit...");#if defined(TAKE_SCREENSHOT) writeppm("sdl.ppm"); #endif SDL_PauseAudio(1); while ( !dev_kbhit() ); SDL_Quit(); if ( mixbuf ) free(mixbuf); return 1;}//void sdl_setpixel(int x, int y, int c){ int offset; if ( x >= 0 && x < screen->w ) { if ( y >= 0 && y < screen->h ) { offset = y * screen->w + x; switch ( bytespp ) { case 1: *(((byte *)screen->pixels)+offset) = c; break; case 2: *(((short int *)screen->pixels)+offset) = c; break; case 4: *(((long int *)screen->pixels)+offset) = c; break; } } }}////#define SDL_FASTPIX(x,y) *(((byte *)screen->pixels)+(y)*screen->w+(x)) = dev_fgcolor#define SDL_FASTPIX(x,y) sdl_setpixel(x,y,cmap[dev_fgcolor])/* Bresenham's algorithm for drawing line */void sdl_line(int X1, int Y1, int X2, int Y2){ int dX, dY, row, col, final, G, inc1, inc2; char pos_slope; dX = X2 - X1; dY = Y2 - Y1; pos_slope = (dX > 0); if ( dY < 0 ) pos_slope = !pos_slope; if ( ABS(dX) > ABS(dY) ) { if (dX > 0) { col = X1; row = Y1; final = X2; } else { col = X2; row = Y2; final = X1; } inc1 = 2 * abs (dY); G = inc1 - abs (dX); inc2 = 2 * (abs (dY) - abs (dX)); if ( pos_slope ) { while (col <= final) { SDL_FASTPIX(col, row); col++; if (G >= 0) { row ++; G += inc2; } else G += inc1; } } else { while (col <= final) { SDL_FASTPIX(col, row); col ++; if (G > 0) { row --; G += inc2; } else G += inc1; } } } /* if |dX| > |dY| */ else { if (dY > 0) { col = X1; row = Y1; final = Y2; } else { col = X2; row = Y2; final = Y1; } inc1 = 2 * abs (dX); G = inc1 - abs (dY); inc2 = 2 * (abs (dX) - abs (dY)); if (pos_slope) { while (row <= final) { SDL_FASTPIX(col, row); row ++; if (G >= 0) { col ++; G += inc2; } else G += inc1; } } else { while (row <= final) { SDL_FASTPIX(col, row); row ++; if (G > 0) { col --; G += inc2; } else G += inc1; } } }}void sdl_fillrect(int x1, int y1, int x2, int y2, int c){ int i, j, dx, count; int offset; if ( y2 > screen->h ) y2 = screen->h; if ( x2 > screen->w ) x2 = screen->w; dx = x2 - x1; count = dx * bytespp; for ( i = y1; i < y2; i ++ ) { offset = i * screen->w * bytespp + x1 * bytespp; switch ( bytespp ) { case 1: memset((char *)screen->pixels+offset, c, count); break; case 2: for ( j = 0; j < dx; j ++ ) { memcpy((char *)screen->pixels+offset, &c, 2); offset += 2; } break; case 4: for ( j = 0; j < dx; j ++ ) { memcpy((char *)screen->pixels+offset, &c, 4); offset += 4; } break; } }}void osd_settextcolor(int fg, int bg){ osd_setcolor(fg); if ( bg != -1 ) dev_bgcolor = bg;}//void osd_drawchar(int x, int y, byte ch, int overwrite, int fg_rgb, int bg_rgb){ int offset; int bit, i; offset = ch * 16; for ( i = 0; i < 16; i ++, offset ++ ) { for ( bit = 0; bit < 8; bit ++ ) { if ( *(font8x16+offset) & (1 << (8-bit)) ) sdl_setpixel(x+bit, y+i, fg_rgb); else if ( overwrite ) sdl_setpixel(x+bit, y+i, bg_rgb); } }}/** enable or disable PEN code*/void osd_setpenmode(int enable){ mouse_mode = enable;}/**/int osd_getpen(int code){ int r = 0; byte update; osd_events(0); if ( mouse_mode ) { switch ( code ) { case 0: // bool: status changed r = mouse_upd; break; case 1: // last pen-down x r = mouse_down_x; break; case 2: // last pen-down y r = mouse_down_y; break; case 3: // vert. 1 = down, 0 = up .... unsupported r = 0; break; case 4: // last x r = mouse_pc_x; break; case 5: // last y r = mouse_pc_y; break; case 10: r = mouse_x; break; case 11: r = mouse_y; break; case 12: case 13: case 14: r = (mouse_b & (1 << (code - 11))) ? 1 : 0; break; } mouse_upd = 0; } return r;}//void osd_cls(){ cur_x = cur_y = 0; SDL_LockSurface(screen); sdl_fillrect(0,0,screen->w,screen->h,cmap[15]); SDL_UnlockSurface(screen);// SDL_UpdateRect(screen, 0, 0, 0, 0);}// returns the current x positionint osd_getx(){ return cur_x;}// returns the current y positionint osd_gety(){ return cur_y;}//void osd_setxy(int x, int y){ cur_x = x; cur_y = y;}/*** next line*/void osd_nextln(){ cur_x = 0; if ( cur_y < ((maxline-1) * font_h) ) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -