SDLCD.c
310 lines
| 8.6 KiB
| text/x-c
|
CLexer
r63 | /*------------------------------------------------------------------------------ | |||
-- 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 | ||||
|
r64 | -- Mail : alexis.jeandet@member.fsf.org | ||
r63 | -------------------------------------------------------------------------------*/ | |||
#include <SDL.h> | ||||
#include <malloc.h> | ||||
#include "SDLCD.h" | ||||
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); | ||||
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, 0); | ||||
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; | ||||
} | ||||
} | ||||
if ( SDL_MUSTLOCK(screen) ) { | ||||
SDL_UnlockSurface(screen); | ||||
} | ||||
SDL_UpdateRect(screen, 0, 0, resx, resy); | ||||
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); | ||||
} | ||||
} | ||||
int SDLCD_init() | ||||
{ | ||||
} | ||||
void SDLCD_writereg(uint32_t reg,uint32_t data) | ||||
{ | ||||
switch (reg) { | ||||
case ILI9328_REGISTER_HORIZONTALGRAMADDRESSSET: | ||||
|
r66 | if((data>=screen->w) || (data<0))printf("Warning printing out of bounds HORIZONTALGRAMADDRESSSET=%d",data); | ||
r63 | SDLCD_Xpos = data; | |||
break; | ||||
case ILI9328_REGISTER_VERTICALGRAMADDRESSSET: | ||||
|
r66 | if((data>=screen->h) || (data<0))printf("Warning printing out of bounds ILI9328_REGISTER_VERTICALGRAMADDRESSSET=%d",data); | ||
r63 | SDLCD_Ypos = data; | |||
break; | ||||
case ILI9328_REGISTER_HORIZONTALADDRESSSTARTPOSITION: | ||||
|
r66 | if((data>=screen->w) || (data<0))printf("Warning printing out of bounds ILI9328_REGISTER_HORIZONTALADDRESSSTARTPOSITION=%d",data); | ||
r63 | SDLCD_XWinStrt = data; | |||
break; | ||||
case ILI9328_REGISTER_HORIZONTALADDRESSENDPOSITION: | ||||
|
r66 | if((data>=screen->w) || (data<0))printf("Warning printing out of bounds ILI9328_REGISTER_HORIZONTALADDRESSENDPOSITION=%d",data); | ||
r63 | SDLCD_XWinEnd = data; | |||
break; | ||||
case ILI9328_REGISTER_VERTICALADDRESSSTARTPOSITION: | ||||
|
r66 | if((data>=screen->h) || (data<0))printf("Warning printing out of bounds ILI9328_REGISTER_VERTICALADDRESSSTARTPOSITION=%d",data); | ||
r63 | SDLCD_YWinStrt = data; | |||
break; | ||||
case ILI9328_REGISTER_VERTICALADDRESSENDPOSITION: | ||||
|
r66 | if((data>=screen->h) || (data<0))printf("Warning printing out of bounds ILI9328_REGISTER_VERTICALADDRESSENDPOSITION=%d",data); | ||
r63 | 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; | ||||
} | ||||
} | ||||
|
r64 | 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; | ||||
} | ||||
r63 | 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++) | ||||
{ | ||||
|
r64 | SDLCD_putpixel_16bpp(screen,SDLCD_Xpos,SDLCD_Ypos,inptr[i]); | ||
r63 | 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); | ||||
} | ||||
|
r64 | // SDL_UpdateRect(screen, SDLCD_XWinStrt, SDLCD_YWinStrt, SDLCD_XWinEnd-SDLCD_XWinStrt, SDLCD_YWinEnd-SDLCD_YWinStrt); | ||
r63 | SDL_UpdateRect(screen, 0, 0, screen->w, screen->h); | |||
} | ||||
|
r64 | 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; | ||||
} | ||||
} | ||||
} | ||||
r63 | 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++) | ||||
{ | ||||
|
r64 | inptr[i]=SDLCD_getpixel_16bpp(screen,SDLCD_Xpos,SDLCD_Ypos); | ||
r63 | 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; | ||||
} | ||||
} | ||||
} | ||||