SDLCD.c
333 lines
| 9.2 KiB
| text/x-c
|
CLexer
r71 | /*------------------------------------------------------------------------------ | |||
-- This file is a part of the libuc, microcontroler library | ||||
-- Copyright (C) 2013, Alexis Jeandet | ||||
-- | ||||
-- 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 3 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 | ||||
------------------------------------------------------------------------------- | ||||
-- Author : Alexis Jeandet | ||||
-- Mail : alexis.jeandet@member.fsf.org | ||||
-------------------------------------------------------------------------------*/ | ||||
#include <SDL.h> | ||||
#include <malloc.h> | ||||
r72 | #include <SDLCD.h> | |||
r71 | ||||
SDL_Surface *screen; | ||||
SDL_Overlay *bmp; | ||||
int SDLCD_Xpos=0; | ||||
int SDLCD_Ypos=0; | ||||
int SDLCD_XWinStrt=0; | ||||
int SDLCD_YWinStrt=0; | ||||
int SDLCD_XWinEnd=0; | ||||
int SDLCD_YWinEnd=0; | ||||
void* SDLCD_buffer; | ||||
int SDLCD_bpp; | ||||
void SDLCD_putpixel(SDL_Surface *surface, int x, int y, Uint32 pixel); | ||||
static Uint32 sdl_refresh_timer(Uint32 interval, void *opaque) { | ||||
if ( SDL_MUSTLOCK(screen) ) { | ||||
if ( SDL_LockSurface(screen) < 0 ) { | ||||
fprintf(stderr, "Can’t lock screen: %s\n", SDL_GetError()); | ||||
return interval; | ||||
} | ||||
} | ||||
//SDL_UpdateRect(screen, 0, 0, screen->w, screen->h); | ||||
SDL_Flip(screen); | ||||
if ( SDL_MUSTLOCK(screen) ) { | ||||
SDL_UnlockSurface(screen); | ||||
} | ||||
return interval; /* 0 means stop timer */ | ||||
} | ||||
void SDLCD_mkscreen(int resx,int resy,int bpp,int lcdtype) | ||||
{ | ||||
int i=0; | ||||
if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER)) { | ||||
fprintf(stderr, "Could not initialize SDL - %s\n", SDL_GetError()); | ||||
exit(1); | ||||
} | ||||
screen = SDL_SetVideoMode(resx, resy, bpp, SDL_DOUBLEBUF); | ||||
if(!screen) { | ||||
fprintf(stderr, "SDL: could not set video mode - exiting\n"); | ||||
exit(1); | ||||
} | ||||
if ( SDL_MUSTLOCK(screen) ) { | ||||
if ( SDL_LockSurface(screen) < 0 ) { | ||||
fprintf(stderr, "Can’t lock screen: %s\n", SDL_GetError()); | ||||
return; | ||||
} | ||||
} | ||||
SDL_UpdateRect(screen, 0, 0, resx, resy); | ||||
if ( SDL_MUSTLOCK(screen) ) { | ||||
SDL_UnlockSurface(screen); | ||||
} | ||||
SDLCD_buffer = malloc(resx*resy*bpp/8); | ||||
SDLCD_bpp = bpp; | ||||
for(i=0;i<(resx*resy);i++) | ||||
{ | ||||
SDLCD_putpixel(screen, i%resx, (i/resx), 0xFFFF); | ||||
} | ||||
SDL_AddTimer(10, sdl_refresh_timer, NULL); | ||||
} | ||||
int SDLCD_init() | ||||
{ | ||||
} | ||||
void SDLCD_writereg(uint32_t reg,uint32_t data) | ||||
{ | ||||
switch (reg) { | ||||
case ILI9328_REGISTER_HORIZONTALGRAMADDRESSSET: | ||||
if((data>=screen->w) || (data<0)) | ||||
printf("Warning printing out of bounds HORIZONTALGRAMADDRESSSET=%d",data); | ||||
SDLCD_Xpos = data; | ||||
break; | ||||
case ILI9328_REGISTER_VERTICALGRAMADDRESSSET: | ||||
if((data>=screen->h) || (data<0)) | ||||
printf("Warning printing out of bounds ILI9328_REGISTER_VERTICALGRAMADDRESSSET=%d",data); | ||||
SDLCD_Ypos = data; | ||||
break; | ||||
case ILI9328_REGISTER_HORIZONTALADDRESSSTARTPOSITION: | ||||
if((data>=screen->w) || (data<0)) | ||||
printf("Warning printing out of bounds ILI9328_REGISTER_HORIZONTALADDRESSSTARTPOSITION=%d",data); | ||||
SDLCD_XWinStrt = data; | ||||
break; | ||||
case ILI9328_REGISTER_HORIZONTALADDRESSENDPOSITION: | ||||
if((data>=screen->w) || (data<0)) | ||||
printf("Warning printing out of bounds ILI9328_REGISTER_HORIZONTALADDRESSENDPOSITION=%d",data); | ||||
SDLCD_XWinEnd = data; | ||||
break; | ||||
case ILI9328_REGISTER_VERTICALADDRESSSTARTPOSITION: | ||||
if((data>=screen->h) || (data<0)) | ||||
printf("Warning printing out of bounds ILI9328_REGISTER_VERTICALADDRESSSTARTPOSITION=%d",data); | ||||
SDLCD_YWinStrt = data; | ||||
break; | ||||
case ILI9328_REGISTER_VERTICALADDRESSENDPOSITION: | ||||
if((data>=screen->h) || (data<0)) | ||||
printf("Warning printing out of bounds ILI9328_REGISTER_VERTICALADDRESSENDPOSITION=%d",data); | ||||
SDLCD_YWinEnd = data; | ||||
break; | ||||
default: | ||||
break; | ||||
} | ||||
} | ||||
uint32_t SDLCD_readreg(uint32_t reg) | ||||
{ | ||||
return 0; | ||||
} | ||||
void SDLCD_putpixel(SDL_Surface *surface, int x, int y, Uint32 pixel) | ||||
{ | ||||
int bpp = surface->format->BytesPerPixel; | ||||
/* Here p is the address to the pixel we want to set */ | ||||
Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * bpp; | ||||
switch(bpp) { | ||||
case 1: | ||||
*p = pixel; | ||||
break; | ||||
case 2: | ||||
*(Uint16 *)p = pixel; | ||||
break; | ||||
case 3: | ||||
if(SDL_BYTEORDER == SDL_BIG_ENDIAN) { | ||||
p[0] = (pixel >> 16) & 0xff; | ||||
p[1] = (pixel >> 8) & 0xff; | ||||
p[2] = pixel & 0xff; | ||||
} else { | ||||
p[0] = pixel & 0xff; | ||||
p[1] = (pixel >> 8) & 0xff; | ||||
p[2] = (pixel >> 16) & 0xff; | ||||
} | ||||
break; | ||||
case 4: | ||||
*(Uint32 *)p = pixel; | ||||
break; | ||||
} | ||||
} | ||||
void SDLCD_putpixel_16bpp(SDL_Surface *surface, int x, int y, Uint32 pixel) | ||||
{ | ||||
Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * surface->format->BytesPerPixel; | ||||
*(Uint16 *)p = pixel; | ||||
} | ||||
Uint32 SDLCD_getpixel_16bpp(SDL_Surface *surface, int x, int y) | ||||
{ | ||||
Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * surface->format->BytesPerPixel; | ||||
return *(Uint16 *)p; | ||||
} | ||||
Uint32 SDLCD_getpixel(SDL_Surface *surface, int x, int y) | ||||
{ | ||||
int bpp = surface->format->BytesPerPixel; | ||||
/* Here p is the address to the pixel we want to retrieve */ | ||||
Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * bpp; | ||||
switch(bpp) { | ||||
case 1: | ||||
return *p; | ||||
case 2: | ||||
return *(Uint16 *)p; | ||||
case 3: | ||||
if(SDL_BYTEORDER == SDL_BIG_ENDIAN) | ||||
return p[0] << 16 | p[1] << 8 | p[2]; | ||||
else | ||||
return p[0] | p[1] << 8 | p[2] << 16; | ||||
case 4: | ||||
return *(Uint32 *)p; | ||||
default: | ||||
return 0; | ||||
} | ||||
/* shouldn’t happen, but avoids warnings */ | ||||
} | ||||
void SDLCD_writeGRAM(void* buffer,uint32_t count) | ||||
{ | ||||
int i=0; | ||||
u_int16_t* ptr=(u_int16_t*)SDLCD_buffer; | ||||
u_int16_t* inptr=(u_int16_t*)buffer; | ||||
if ( SDL_MUSTLOCK(screen) ) { | ||||
if ( SDL_LockSurface(screen) < 0 ) { | ||||
fprintf(stderr, "Can’t lock screen: %s\n", SDL_GetError()); | ||||
return; | ||||
} | ||||
} | ||||
for(i=0;i<count;i++) | ||||
{ | ||||
SDLCD_putpixel_16bpp(screen,SDLCD_Xpos,SDLCD_Ypos,inptr[i]); | ||||
SDLCD_Xpos+=1; | ||||
ptr[i]=inptr[i]; | ||||
if(SDLCD_Xpos>=SDLCD_XWinEnd) | ||||
{ | ||||
SDLCD_Xpos=SDLCD_XWinStrt; | ||||
SDLCD_Ypos+=1; | ||||
} | ||||
if(SDLCD_Ypos>=SDLCD_YWinEnd) | ||||
{ | ||||
SDLCD_Ypos=SDLCD_YWinStrt; | ||||
} | ||||
} | ||||
if ( SDL_MUSTLOCK(screen) ) { | ||||
SDL_UnlockSurface(screen); | ||||
} | ||||
// SDL_UpdateRect(screen, SDLCD_XWinStrt, SDLCD_YWinStrt, SDLCD_XWinEnd-SDLCD_XWinStrt, SDLCD_YWinEnd-SDLCD_YWinStrt); | ||||
//SDL_UpdateRect(screen, 0, 0, screen->w, screen->h); | ||||
} | ||||
void SDLCD_writeGRAM_16bpp(void* buffer,uint32_t count) | ||||
{ | ||||
int i=0; | ||||
u_int16_t* inptr=(u_int16_t*)buffer; | ||||
if ( SDL_MUSTLOCK(screen) ) { | ||||
if ( SDL_LockSurface(screen) < 0 ) { | ||||
fprintf(stderr, "Can’t lock screen: %s\n", SDL_GetError()); | ||||
return; | ||||
} | ||||
} | ||||
for(i=0;i<count;i++) | ||||
{ | ||||
*(( Uint16 * ) screen->pixels + SDLCD_Ypos * screen->pitch / 2 + SDLCD_Xpos)=inptr[i]; | ||||
SDLCD_Xpos+=1; | ||||
if(SDLCD_Xpos>=SDLCD_XWinEnd) | ||||
{ | ||||
SDLCD_Xpos=SDLCD_XWinStrt; | ||||
SDLCD_Ypos+=1; | ||||
} | ||||
if(SDLCD_Ypos>=SDLCD_YWinEnd) | ||||
{ | ||||
SDLCD_Ypos=SDLCD_YWinStrt; | ||||
} | ||||
} | ||||
if ( SDL_MUSTLOCK(screen) ) { | ||||
SDL_UnlockSurface(screen); | ||||
} | ||||
// SDL_UpdateRect(screen, SDLCD_XWinStrt, SDLCD_YWinStrt, SDLCD_XWinEnd-SDLCD_XWinStrt, SDLCD_YWinEnd-SDLCD_YWinStrt); | ||||
//SDL_UpdateRect(screen, 0, 0, screen->w, screen->h); | ||||
} | ||||
void SDLCD_readGRAM_16bpp(void* buffer,uint32_t count) | ||||
{ | ||||
int i=0; | ||||
u_int16_t* ptr=(u_int16_t*)SDLCD_buffer; | ||||
u_int16_t* inptr=(u_int16_t*)buffer; | ||||
for(i=0;i<count;i++) | ||||
{ | ||||
inptr[i]=*(( Uint16 * ) screen->pixels + SDLCD_Ypos * screen->pitch / 2 + SDLCD_Xpos); | ||||
SDLCD_Xpos+=1; | ||||
ptr[i]=inptr[i]; | ||||
if(SDLCD_Xpos>=SDLCD_XWinEnd) | ||||
{ | ||||
SDLCD_Xpos=SDLCD_XWinStrt; | ||||
SDLCD_Ypos+=1; | ||||
} | ||||
if(SDLCD_Ypos>=SDLCD_YWinEnd) | ||||
{ | ||||
SDLCD_Ypos=SDLCD_YWinStrt; | ||||
} | ||||
} | ||||
} | ||||
void SDLCD_readGRAM(void* buffer,uint32_t count) | ||||
{ | ||||
int i=0; | ||||
u_int16_t* ptr=(u_int16_t*)SDLCD_buffer; | ||||
u_int16_t* inptr=(u_int16_t*)buffer; | ||||
for(i=0;i<count;i++) | ||||
{ | ||||
inptr[i]=SDLCD_getpixel_16bpp(screen,SDLCD_Xpos,SDLCD_Ypos); | ||||
SDLCD_Xpos+=1; | ||||
ptr[i]=inptr[i]; | ||||
if(SDLCD_Xpos>=SDLCD_XWinEnd) | ||||
{ | ||||
SDLCD_Xpos=SDLCD_XWinStrt; | ||||
SDLCD_Ypos+=1; | ||||
} | ||||
if(SDLCD_Ypos>=SDLCD_YWinEnd) | ||||
{ | ||||
SDLCD_Ypos=SDLCD_YWinStrt; | ||||
} | ||||
} | ||||
} | ||||