diff options
Diffstat (limited to 'source/framebuffer.c')
-rw-r--r-- | source/framebuffer.c | 386 |
1 files changed, 386 insertions, 0 deletions
diff --git a/source/framebuffer.c b/source/framebuffer.c new file mode 100644 index 0000000..0884f76 --- /dev/null +++ b/source/framebuffer.c @@ -0,0 +1,386 @@ +/* + ds81 - Nintendo DS ZX81 emulator. + + Copyright (C) 2006 Ian Cowburn <ianc@noddybox.co.uk> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + $Id: framebuffer.c 43 2007-03-12 00:59:51Z ianc $ +*/ + +#include <nds.h> +#include <stdio.h> +#include <stdarg.h> +#include <string.h> + +#include "framebuffer.h" + +/* ---------------------------------------- STATIC DATA +*/ +#define WIDTH 256 +#define SCAN 128 +#define HEIGHT 192 + +static uint16 *buff; +static uint16 *pal; + +static uint8 font[]= +{ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x08, 0x08, 0x08, 0x08, 0x00, 0x08, 0x00, + 0x00, 0x24, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0x7e, 0x24, 0x24, 0x7e, 0x24, 0x00, + 0x00, 0x10, 0x7c, 0x14, 0x7c, 0x50, 0x7c, 0x10, + 0x00, 0x46, 0x26, 0x10, 0x08, 0x64, 0x62, 0x00, + 0x00, 0x08, 0x14, 0x08, 0x54, 0x22, 0x5c, 0x00, + 0x00, 0x10, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x20, 0x10, 0x10, 0x10, 0x10, 0x20, 0x00, + 0x00, 0x04, 0x08, 0x08, 0x08, 0x08, 0x04, 0x00, + 0x00, 0x00, 0x28, 0x10, 0x7c, 0x10, 0x28, 0x00, + 0x00, 0x00, 0x10, 0x10, 0x7c, 0x10, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x08, + 0x00, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, + 0x00, 0x00, 0x40, 0x20, 0x10, 0x08, 0x04, 0x00, + 0x00, 0x3c, 0x62, 0x52, 0x4a, 0x46, 0x3c, 0x00, + 0x00, 0x18, 0x14, 0x10, 0x10, 0x10, 0x7c, 0x00, + 0x00, 0x3c, 0x42, 0x40, 0x3c, 0x02, 0x7e, 0x00, + 0x00, 0x3c, 0x42, 0x30, 0x40, 0x42, 0x3c, 0x00, + 0x00, 0x10, 0x18, 0x14, 0x12, 0x7e, 0x10, 0x00, + 0x00, 0x7e, 0x02, 0x3e, 0x40, 0x42, 0x3c, 0x00, + 0x00, 0x3c, 0x02, 0x3e, 0x42, 0x42, 0x3c, 0x00, + 0x00, 0x7e, 0x40, 0x20, 0x10, 0x08, 0x08, 0x00, + 0x00, 0x3c, 0x42, 0x3c, 0x42, 0x42, 0x3c, 0x00, + 0x00, 0x3c, 0x42, 0x42, 0x7c, 0x40, 0x3c, 0x00, + 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, + 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x08, 0x04, + 0x00, 0x00, 0x20, 0x10, 0x08, 0x10, 0x20, 0x00, + 0x00, 0x00, 0x00, 0x7c, 0x00, 0x7c, 0x00, 0x00, + 0x00, 0x00, 0x08, 0x10, 0x20, 0x10, 0x08, 0x00, + 0x00, 0x3c, 0x42, 0x20, 0x10, 0x00, 0x10, 0x00, + 0x00, 0x3c, 0x52, 0x6a, 0x7a, 0x02, 0x3c, 0x00, + 0x00, 0x3c, 0x42, 0x42, 0x7e, 0x42, 0x42, 0x00, + 0x00, 0x3e, 0x42, 0x3e, 0x42, 0x42, 0x3e, 0x00, + 0x00, 0x3c, 0x42, 0x02, 0x02, 0x42, 0x3c, 0x00, + 0x00, 0x1e, 0x22, 0x42, 0x42, 0x22, 0x1e, 0x00, + 0x00, 0x7e, 0x02, 0x3e, 0x02, 0x02, 0x7e, 0x00, + 0x00, 0x7e, 0x02, 0x3e, 0x02, 0x02, 0x02, 0x00, + 0x00, 0x3c, 0x42, 0x02, 0x72, 0x42, 0x3c, 0x00, + 0x00, 0x42, 0x42, 0x7e, 0x42, 0x42, 0x42, 0x00, + 0x00, 0x7c, 0x10, 0x10, 0x10, 0x10, 0x7c, 0x00, + 0x00, 0x40, 0x40, 0x40, 0x42, 0x42, 0x3c, 0x00, + 0x00, 0x22, 0x12, 0x0e, 0x12, 0x22, 0x42, 0x00, + 0x00, 0x02, 0x02, 0x02, 0x02, 0x02, 0x7e, 0x00, + 0x00, 0x42, 0x66, 0x5a, 0x42, 0x42, 0x42, 0x00, + 0x00, 0x42, 0x46, 0x4a, 0x52, 0x62, 0x42, 0x00, + 0x00, 0x3c, 0x42, 0x42, 0x42, 0x42, 0x3c, 0x00, + 0x00, 0x3e, 0x42, 0x42, 0x3e, 0x02, 0x02, 0x00, + 0x00, 0x3c, 0x42, 0x42, 0x4a, 0x52, 0x3c, 0x00, + 0x00, 0x3e, 0x42, 0x42, 0x3e, 0x22, 0x42, 0x00, + 0x00, 0x3c, 0x02, 0x3c, 0x40, 0x42, 0x3c, 0x00, + 0x00, 0x7f, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, + 0x00, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3c, 0x00, + 0x00, 0x42, 0x42, 0x42, 0x42, 0x24, 0x18, 0x00, + 0x00, 0x42, 0x42, 0x42, 0x42, 0x5a, 0x24, 0x00, + 0x00, 0x42, 0x24, 0x18, 0x18, 0x24, 0x42, 0x00, + 0x00, 0x41, 0x22, 0x14, 0x08, 0x08, 0x08, 0x00, + 0x00, 0x7e, 0x20, 0x10, 0x08, 0x04, 0x7e, 0x00, + 0x00, 0x70, 0x10, 0x10, 0x10, 0x10, 0x70, 0x00, + 0x00, 0x00, 0x02, 0x04, 0x08, 0x10, 0x20, 0x00, + 0x00, 0x0e, 0x08, 0x08, 0x08, 0x08, 0x0e, 0x00, + 0x00, 0x08, 0x1c, 0x2a, 0x08, 0x08, 0x08, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, + 0x00, 0x38, 0x44, 0x1e, 0x04, 0x04, 0x7e, 0x00, + 0x00, 0x00, 0x1c, 0x20, 0x3c, 0x22, 0x3c, 0x00, + 0x00, 0x04, 0x04, 0x3c, 0x44, 0x44, 0x3c, 0x00, + 0x00, 0x00, 0x38, 0x04, 0x04, 0x04, 0x38, 0x00, + 0x00, 0x20, 0x20, 0x3c, 0x22, 0x22, 0x3c, 0x00, + 0x00, 0x00, 0x1c, 0x22, 0x1e, 0x02, 0x3c, 0x00, + 0x00, 0x30, 0x08, 0x18, 0x08, 0x08, 0x08, 0x00, + 0x00, 0x00, 0x3c, 0x22, 0x22, 0x3c, 0x20, 0x1c, + 0x00, 0x02, 0x02, 0x1e, 0x22, 0x22, 0x22, 0x00, + 0x00, 0x08, 0x00, 0x0c, 0x08, 0x08, 0x1c, 0x00, + 0x00, 0x20, 0x00, 0x20, 0x20, 0x20, 0x24, 0x18, + 0x00, 0x04, 0x14, 0x0c, 0x0c, 0x14, 0x24, 0x00, + 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x30, 0x00, + 0x00, 0x00, 0x16, 0x2a, 0x2a, 0x2a, 0x2a, 0x00, + 0x00, 0x00, 0x1e, 0x22, 0x22, 0x22, 0x22, 0x00, + 0x00, 0x00, 0x1c, 0x22, 0x22, 0x22, 0x1c, 0x00, + 0x00, 0x00, 0x1e, 0x22, 0x22, 0x1e, 0x02, 0x02, + 0x00, 0x00, 0x3c, 0x22, 0x22, 0x3c, 0x20, 0x60, + 0x00, 0x00, 0x38, 0x04, 0x04, 0x04, 0x04, 0x00, + 0x00, 0x00, 0x1c, 0x02, 0x1c, 0x20, 0x1e, 0x00, + 0x00, 0x08, 0x1c, 0x08, 0x08, 0x08, 0x30, 0x00, + 0x00, 0x00, 0x22, 0x22, 0x22, 0x22, 0x1c, 0x00, + 0x00, 0x00, 0x22, 0x22, 0x14, 0x14, 0x08, 0x00, + 0x00, 0x00, 0x22, 0x2a, 0x2a, 0x2a, 0x14, 0x00, + 0x00, 0x00, 0x22, 0x14, 0x08, 0x14, 0x22, 0x00, + 0x00, 0x00, 0x22, 0x22, 0x22, 0x3c, 0x20, 0x1c, + 0x00, 0x00, 0x3e, 0x10, 0x08, 0x04, 0x3e, 0x00, + 0x00, 0x70, 0x10, 0x0c, 0x10, 0x10, 0x70, 0x00, + 0x00, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, + 0x00, 0x0e, 0x08, 0x30, 0x08, 0x08, 0x0e, 0x00, + 0x00, 0x28, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x3c, 0x42, 0x99, 0x85, 0x85, 0x99, 0x42, 0x3c +}; + + +/* ---------------------------------------- PRIVATE INTERFACES +*/ +static inline void Plot(int x, int y, int col) +{ + uint16 *base; + uint16 cur; + int odd; + + if (col == -1) + return; + + odd = x&1; + x /= 2; + + base = buff+x+y*SCAN; + cur = *base; + + if (odd) + { + cur = (cur & 0xff) | (col<<8); + } + else + { + cur = (cur & 0xff00) | col; + } + + *base = cur; +} + + +/* ---------------------------------------- PUBLIC INTERFACES +*/ +void FB_Init(uint16 *vram, uint16 *palette) +{ + buff = vram; + pal = palette; + + pal[COL_BLACK] = RGB15(0,0,0); + pal[COL_WHITE] = RGB15(31,31,31); + pal[COL_RED] = RGB15(31,0,0); + pal[COL_GREEN] = RGB15(0,31,0); + pal[COL_BLUE] = RGB15(0,0,31); + pal[COL_GUISELECT] = RGB15(8,8,31); + pal[COL_GREY] = RGB15(15,15,15); + pal[COL_LIGHTGREY] = RGB15(22,22,22); + pal[COL_DARKGREY] = RGB15(8,8,8); + pal[COL_YELLOW] = RGB15(31,31,0); +} + + +uint16 *FB_VRAM(void) +{ + return buff; +} + + +uint16 *FB_PALETTE(void) +{ + return pal; +} + + +void FB_LoadASCIITiles(uint16 *tiles) +{ + uint8 *src; + int c; + int row; + int val; + int mask; + + src = font; + + for(c = 32; c < 127; c++) + { + for(row = 0; row < 8; row++) + { + for(mask = 1; mask < 0xff; mask<<=1) + { + if (*src & mask) + { + val = COL_WHITE; + } + else + { + val = 0; + } + + mask <<= 1; + + if (*src & mask) + { + val |= COL_WHITE << 8; + } + + *tiles++ = val; + } + + src++; + } + } +} + + +void FB_Print(const char *text, int x, int y, FB_Colour colour, FB_Colour paper) +{ + int cx,cy; + int ch; + + while(*text) + { + ch=((*text)-32)*8; + + for(cy=0;cy<8;cy++) + { + for(cx=0;cx<8;cx++) + { + if (font[ch]&(1<<cx)) + { + Plot(x+cx, y+cy, colour); + } + else + { + Plot(x+cx, y+cy, paper); + } + } + + ch++; + } + + x+=8; + text++; + } +} + + +void FB_Centre(const char *text, int y, FB_Colour colour, FB_Colour paper) +{ + FB_Print(text,WIDTH/2-strlen(text)*4,y,colour,paper); +} + + +void FB_printf(int x, int y, FB_Colour colour, FB_Colour paper, + const char *format, ...) +{ + char buff[80]; + va_list va; + + va_start(va,format); + vsnprintf(buff,sizeof buff,format,va); + va_end(va); + + FB_Print(buff,x,y,colour,paper); +} + + +void FB_HLine(int x1, int x2, int y, FB_Colour colour) +{ + uint16 *line; + + line=buff+y*WIDTH+x1; + + while(x1<=x2) + { + Plot(x1++,y,colour); + } +} + + +void FB_VLine(int x, int y1, int y2, FB_Colour colour) +{ + while(y1<=y2) + { + Plot(x,y1++,colour); + } +} + + +void FB_Box(int x, int y, int w, int h, FB_Colour colour) +{ + FB_HLine(x,x+w-1,y,colour); + FB_HLine(x,x+w-1,y+h-1,colour); + FB_VLine(x,y,y+h-1,colour); + FB_VLine(x+w-1,y,y+h-1,colour); +} + + +void FB_FillBox(int x, int y, int w, int h, FB_Colour colour) +{ + while(h--) + { + FB_HLine(x,x+w-1,y++,colour); + } +} + + +void FB_Clear(void) +{ + uint16 *p; + int f; + + f=WIDTH*HEIGHT/2; + p=buff; + + while(f--) + { + *p++=0; + } +} + + +void FB_Blit(sImage *img, int x, int y, int offset) +{ + uint16 *dest; + uint16 *row; + uint8 *src; + uint16 pix; + int hww; + int ht; + int f; + + x /= 2; + + ht = img->height; + hww = img->width / 2; + dest = buff+x+y*SCAN; + src = img->image.data8; + + for(f=0;f<16;f++) + { + pal[offset+f] = img->palette[f]; + } + + while(ht--) + { + row = dest; + + for(f=0;f<hww;f++) + { + pix = *src++ + offset; + pix |= (*src++ + offset) << 8; + + *row++ = pix; + } + + dest += SCAN; + } +} |