0 Members and 1 Guest are viewing this topic.
#define _WIN32_WINNT 0x0500 #include <windows.h>#include <mmsystem.h>#include <vfw.h>#include <wincon.h>#include <stdlib.h>#include <string.h>#include <stdio.h>#include <limits.h>#include <assert.h>#define SCREEN_WIDTH 80#define SCREEN_HEIGHT 25#define FIRST_CHAR 32#define LAST_CHAR 255//#define FIRST_CHAR '0'//#define LAST_CHAR '9'#define NUM_CHARS (LAST_CHAR-FIRST_CHAR)CHAR_INFO screen[SCREEN_WIDTH*SCREEN_HEIGHT];void Sprite(int xx, int yy, unsigned int *spr, unsigned int w, unsigned int h);struct{ unsigned int rgb; unsigned int h,s,v;} colourtable[NUM_CHARS][256];struct{ unsigned int fg; unsigned int bg; unsigned int rf,gf,bf; unsigned int rb,gb,bb;} colours[256];struct{ unsigned char ch; unsigned char col;} lookup[32768];unsigned int myabs(int x){ return x>=0?x:-x;}void loadimage(const char *fname, unsigned int **buffer){ struct { BITMAPINFOHEADER bmih; RGBQUAD bmic[4]; } bmp={0}; HBITMAP hbm; HDC hdc; hbm = (HBITMAP)LoadImage(NULL, fname, IMAGE_BITMAP, 0,0, LR_LOADFROMFILE); hdc = GetDC(NULL); bmp.bmih.biSize = sizeof(BITMAPINFOHEADER); GetDIBits(hdc, hbm, 0,0, NULL, (BITMAPINFO *)&bmp, 0); bmp.bmih.biBitCount = 32; *buffer = new unsigned int [myabs(bmp.bmih.biHeight)*bmp.bmih.biWidth]; GetDIBits(hdc, hbm, 0, bmp.bmih.biHeight, *buffer, (BITMAPINFO *)&bmp, DIB_RGB_COLORS); ReleaseDC(NULL, hdc); DeleteObject((HGDIOBJ)hbm); int w = bmp.bmih.biWidth; int h = myabs(bmp.bmih.biHeight); unsigned int tmp[2048]; unsigned int *src = *buffer; unsigned int *dst = *buffer+(h-1)*w; int y; for (y = 0; y < h/2; y++) { memcpy(tmp, src, w*sizeof *src); memcpy(src, dst, w*sizeof *src); memcpy(dst, tmp, w*sizeof *src); src += w; dst -= w; }}void freeimage(unsigned int *buffer){ delete [] buffer;}PAVISTREAM avistream;HDC avihdc;HBITMAP avibmp;unsigned int currframe;PGETFRAME frame;unsigned int fps;bool openavi(const char *fname){ AVISTREAMINFO info; if (AVIStreamOpenFromFile(&avistream, fname, streamtypeVIDEO, 0, OF_READ, NULL)) return false; if ((frame = AVIStreamGetFrameOpen(avistream, NULL))==NULL) return false; AVIStreamLength(avistream); AVIStreamInfo(avistream, &info, sizeof info); fps = info.dwRate/info.dwScale; currframe = 0; HDC hdc = GetDC(NULL); avihdc = CreateCompatibleDC(hdc); avibmp = CreateCompatibleBitmap(hdc, SCREEN_WIDTH, SCREEN_HEIGHT); SetStretchBltMode(avihdc, HALFTONE); SetBrushOrgEx(avihdc, 0,0, NULL); SelectObject(avihdc, avibmp); ReleaseDC(NULL, hdc); return true;}bool avigetframe(void){ BITMAPINFOHEADER *bmi; unsigned int avispr[SCREEN_WIDTH*SCREEN_HEIGHT]; struct { BITMAPINFOHEADER bmih; RGBQUAD bmic[4]; } bmp={0}; bmp.bmih.biSize = sizeof(BITMAPINFOHEADER); bmi = (BITMAPINFOHEADER *)AVIStreamGetFrame(frame, currframe++); if (bmi == NULL) return false; StretchDIBits(avihdc, 0,0, SCREEN_WIDTH,SCREEN_HEIGHT, 0,0, bmi->biWidth,bmi->biHeight, (void *)(bmi+1), (BITMAPINFO *)bmi, DIB_RGB_COLORS, SRCCOPY); GetDIBits(avihdc, avibmp, 0,0, NULL, (BITMAPINFO *)&bmp, 0); GetDIBits(avihdc, avibmp, 0,SCREEN_HEIGHT, avispr, (BITMAPINFO *)&bmp, DIB_RGB_COLORS); int w = bmp.bmih.biWidth; int h = myabs(bmp.bmih.biHeight); unsigned int tmp[2048]; unsigned int *src = avispr; unsigned int *dst = avispr+(h-1)*w; int y; for (y = 0; y < h/2; y++) { memcpy(tmp, src, w*sizeof *src); memcpy(src, dst, w*sizeof *src); memcpy(dst, tmp, w*sizeof *src); src += w; dst -= w; } Sprite(0,0,avispr,SCREEN_WIDTH, SCREEN_HEIGHT); return true;}void avirestart(void){ currframe = 0;}void closeavi(void){ DeleteObject(avibmp); DeleteDC(avihdc); AVIStreamGetFrameClose(frame); AVIStreamRelease(avistream);}void rgb2hsv(unsigned int r, unsigned int g, unsigned int b, unsigned int *h, unsigned int *s, unsigned int *v){ unsigned int mn, mx; int d; int ht; if (r <= g && r <= b) mn = r; else if (g <= r && g <= b) mn = g; else mn = b; if (r >= g && r >= b) mx = r; else if (g >= r && g >= b) mx = g; else mx = b; d = mx - mn; *v = mx; if (mx == 0 || (mx-mn) == 0) { *s = 0; *h = 0; } else { *s = (d<<8)/mx; if (mx == r) ht = (int)((g-b)<<8)/d; else if (mx == g) ht = 512+(int)((b-r)<<8)/d; else ht = 1024+(int)((r-g)<<8)/d; ht = (ht*60)>>8; if (ht < 0) ht += 360; *h = ht; }}void buildcolourtable(void){ unsigned int rf,gf,bf; unsigned int rb,gb,bb; unsigned int x; for (x = 0; x < 256; x++) { if (x&FOREGROUND_BLUE) bf = 127; else bf = 0; if (x&FOREGROUND_GREEN) gf = 127; else gf = 0; if (x&FOREGROUND_RED) rf = 127; else rf = 0; if (x&FOREGROUND_INTENSITY) { bf<<=1; gf<<=1; rf<<=1; } if (x&BACKGROUND_BLUE) bb = 127; else bb = 0; if (x&BACKGROUND_GREEN) gb = 127; else gb = 0; if (x&BACKGROUND_RED) rb = 127; else rb = 0; if (x&BACKGROUND_INTENSITY) { bb<<=1; gb<<=1; rb<<=1; } colours[x].fg = (rf<<16)|(gf<<8)|bf; colours[x].rf = rf; colours[x].gf = gf; colours[x].bf = bf; colours[x].bg = (rb<<16)|(gb<<8)|bb; colours[x].rb = rb; colours[x].gb = gb; colours[x].bb = bb; }}unsigned char colourmatch(unsigned int rgb, unsigned char *ch){ unsigned int r,g,b; unsigned int h,s,v; int dh,ds,dv; unsigned int x; unsigned int dist, d; unsigned int fx,fz; r = rgb&0xff0000; g = rgb&0x00ff00; b = rgb&0x0000ff; rgb2hsv(r>>16,g>>8,b,&h,&s,&v); dist = UINT_MAX; fx=fz=0; for (x = 0; x < NUM_CHARS; x++) { for (int z = 0; z < 256; z++) { //dh=ds=dv=0; dh = h - colourtable[x][z].h; ds = s - colourtable[x][z].s; dv = v - colourtable[x][z].v; d = dh*dh + ds*ds + dv*dv; if (d < dist) { dist = d; fz = z; fx = x; } } } *ch = (unsigned char)(FIRST_CHAR+fx); return (unsigned char)fz;}unsigned char lookupcolourmatch(unsigned int rgb, unsigned char *ch){ rgb = ((rgb>>3)&0x001f)|((rgb>>6)&0x3e0)|((rgb>>9)&0x7c00); *ch = lookup[rgb].ch; return lookup[rgb].col;}void createlookup(void){ unsigned int r,g,b,rgb; unsigned int x; for (x = 0; x < 32768; x++) { r = x&0x7C00; g = x&0x3E0; b = x&0x1F; rgb = (r<<9)|(g<<6)|(b<<3); rgb |= (rgb>>5)&0x070707; lookup[x].col = colourmatch(rgb, &lookup[x].ch); }}void create_colours(unsigned int c, unsigned int *bmp, unsigned int w, unsigned int h, unsigned int bg, unsigned fg){ unsigned int scale = w*h; unsigned int r,g,b; int x; bmp; for (x = 0; x < 256; x++) { r = (bg*colours[x].rb + fg*colours[x].rf)/scale; g = (bg*colours[x].gb + fg*colours[x].gf)/scale; b = (bg*colours[x].bb + fg*colours[x].bf)/scale; if (r>255) r = 255; if (g>255) g = 255; if (b>255) b = 255; colourtable[c-FIRST_CHAR][x].rgb = (r<<16)|(g<<8)|b; rgb2hsv(r,g,b,&colourtable[c-FIRST_CHAR][x].h, &colourtable[c-FIRST_CHAR][x].s, &colourtable[c-FIRST_CHAR][x].v); }}void compute_colours(HFONT font, unsigned int w, unsigned int h){ HDC hdc,hdc2; HBITMAP memBM; hdc = GetDC(NULL); hdc2 = CreateCompatibleDC(hdc); memBM = CreateCompatibleBitmap(hdc,w,h); ReleaseDC(NULL, hdc);Â Â SelectObject(hdc2, memBM); SelectObject(hdc2, font); unsigned int *letter = new unsigned int[w*h]; buildcolourtable(); unsigned int x,d,a; for (x = FIRST_CHAR; x <= LAST_CHAR; x++) { char xstr[1]; xstr[0]=(char)x; TextOut(hdc2, 0,0, xstr, 1); unsigned int bg,fg; bg=fg=0; for (d = 0; d < h; d++) { for (a = 0; a < w; a++) { letter[a+d*w] = (unsigned int)GetPixel(hdc2, a,d); if (letter[a+d*w]==0xffffff) bg++; else fg++; } } create_colours(x,letter,w,h,bg,fg); } delete [] letter; DeleteObject(memBM); DeleteDC(hdc2); createlookup();}void Print(int xx, int yy, const char *string, unsigned char colour){ size_t len; len = strlen(string); CHAR_INFO *dst; dst = &screen[xx+yy*SCREEN_WIDTH]; while (len--) { dst->Char.AsciiChar = *string++; dst->Attributes = colour; dst++; }}void Plot(int x, int y, unsigned int colour){ CHAR_INFO *dst; dst = &screen[x+y*SCREEN_WIDTH]; dst->Attributes = lookupcolourmatch(colour, (unsigned char *)&dst->Char.AsciiChar);}void Sprite(int xx, int yy, unsigned int *spr, unsigned int w, unsigned int h){ int x, y; CHAR_INFO *dst; dst = &screen[xx+yy*SCREEN_WIDTH]; for (y = yy; y < (int)(yy+h); y++) { for (x = xx; x < (int)(xx+w); x++) { dst->Attributes = lookupcolourmatch(*spr++, (unsigned char *)&dst->Char.AsciiChar); dst++; } dst += SCREEN_WIDTH-w; }}int main(void){ HANDLE output; COORD size = {SCREEN_WIDTH,SCREEN_HEIGHT}; COORD origin = {0,0}; SMALL_RECT dim = {0,0,SCREEN_WIDTH-1,SCREEN_HEIGHT-1}; CONSOLE_FONT_INFO fonti; COORD fontsize; HFONT font; timeBeginPeriod(1); AVIFileInit(); //create the console output = CreateConsoleScreenBuffer(GENERIC_WRITE|GENERIC_READ , 0, NULL, CONSOLE_TEXTMODE_BUFFER, NULL); SetConsoleActiveScreenBuffer(output); SetConsoleScreenBufferSize(output, size); GetCurrentConsoleFont(output, TRUE, &fonti); fontsize = GetConsoleFontSize(output, fonti.nFont); //unsigned int *bee; //loadimage(NULL, &bee); OPENFILENAME op; char filename[_MAX_PATH]; char *load_ext=".avi"; BOOL res; filename[0] = '\0'; op.lStructSize = sizeof(OPENFILENAME); op.hwndOwner = NULL; op.hInstance = 0; op.lpstrFilter = "AVI Files\0*.avi\0All Files\0*\0"; op.lpstrCustomFilter = NULL; op.nMaxCustFilter = 0; op.nFilterIndex = 0;//curr_file_ext; op.lpstrFile = filename;// <- default file name op.nMaxFile = _MAX_PATH; op.lpstrFileTitle = NULL; op.nMaxFileTitle = 0; op.lpstrInitialDir = NULL;// <- default dir op.lpstrTitle = "Select File to Load"; op.Flags = OFN_ENABLESIZING|OFN_FILEMUSTEXIST|OFN_EXPLORER|OFN_LONGNAMES|OFN_NOREADONLYRETURN|OFN_PATHMUSTEXIST; op.nFileOffset = 0; op.nFileExtension = 0; op.lpstrDefExt = load_ext; op.lCustData = 0; op.lpfnHook = NULL; op.lpTemplateName = NULL; res = GetOpenFileName(&op); if (!res) goto novid; if (!openavi(filename)) { MessageBox(NULL, "Sorry, that AVI file can't be played.", "Video Error", MB_ICONERROR|MB_OK); goto novid; } //graphics version of console font font = CreateFont( -fontsize.Y, fontsize.X, 0,0, FW_DONTCARE, 0,0,0, OEM_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, NONANTIALIASED_QUALITY, FIXED_PITCH|FF_DONTCARE, "Terminal" ); compute_colours(font, fontsize.X, fontsize.Y); DeleteObject(font); LARGE_INTEGER pc,fq,ti; QueryPerformanceFrequency(&fq); QueryPerformanceCounter(&pc); for (;;) { if (!avigetframe()) { avirestart(); avigetframe(); } //Sprite(0,0,bee,80,25); QueryPerformanceCounter(&ti); char tmp[256]; sprintf(tmp, "%3.2f", (double)fq.QuadPart/(ti.QuadPart-pc.QuadPart)); Print(0,0,tmp,FOREGROUND_RED|BACKGROUND_RED|BACKGROUND_GREEN|BACKGROUND_BLUE|BACKGROUND_INTENSITY|FOREGROUND_INTENSITY); pc = ti; WriteConsoleOutput(output, screen, size, origin, &dim); if (GetAsyncKeyState(VK_ESCAPE)) break; Sleep(1000/fps); } closeavi();novid: CloseHandle(output); AVIFileExit(); timeEndPeriod(1); return 0;}