3 * Iter Vehemens ad Necem (IVAN)
4 * Copyright (C) Timo Kiviluoto
5 * Released under the GNU General
8 * See LICENSING which should be included
9 * along with this file for more details
23 void (*graphics::SwitchModeHandler
) ();
25 SDL_Surface
*graphics::Screen
;
27 bitmap
*graphics::DoubleBuffer
;
29 int graphics::ColorDepth
;
30 rawbitmap
*graphics::DefaultFont
= 0;
33 truth origDblRes
= false;
35 //#define DIVISOR (1.7)
39 static int fixVal (int v
) { return (dblRes
? (int)(v
*DIVISOR
) : v
); }
42 float frc0
, frc1
, yfrc0
, yfrc1
;
48 unsigned char *bufc32
= 0;
50 static void freeKernel () {
51 if (kernel
) { free(kernel
); kernel
= 0; }
55 static void buildKernel (int resx
, int resy
) {
56 KIt
* res
= (KIt
*)malloc(fixVal(resy
)*fixVal(resx
)*sizeof(KIt
));
57 for (int y
= 0; y
< fixVal(resy
); ++y
) {
58 for (int x
= 0; x
< fixVal(resx
); ++x
) {
59 KIt
* i
= res
+y
*fixVal(resx
)+x
;
62 float frc1
= fx
-(int)fx
;
63 float frc0
= 1.0-frc1
;
64 float yfrc1
= fy
-(int)fy
;
65 float yfrc0
= 1.0-yfrc1
;
70 //r[0] = (r[0]*frc0+r[1]*frc1)*yfrc0+(r[2]*frc0+r[3]*frc1)*yfrc1;
71 for (int dy
= 0; dy
< 2; ++dy
) {
72 for (int dx
= 0; dx
< 2; ++dx
) {
73 int sx
= (int)(fx
+dx
);
74 int sy
= (int)(fy
+dy
);
75 if (sx
>= 0 && sy
>= 0 && sx
< resx
&& sy
< resy
) {
76 i
->sofs
[dy
*2+dx
] = sy
*(resx
*4)+sx
*4;
90 void graphics::Init () {
91 static truth AlreadyInstalled
= false;
92 if (!AlreadyInstalled
) {
93 AlreadyInstalled
= true;
94 if (SDL_Init(SDL_INIT_VIDEO
| SDL_INIT_TIMER
| SDL_INIT_NOPARACHUTE
)) ABORT("Can't initialize SDL.");
95 atexit(graphics::DeInit
);
100 void graphics::DeInit () {
107 void graphics::SetMode (cchar
*Title
, cchar
*IconName
, v2 NewRes
, truth FullScreen
, sLong adresmod
) {
109 SDL_Surface
*Icon
= SDL_LoadBMP(IconName
);
110 SDL_SetColorKey(Icon
, SDL_SRCCOLORKEY
, SDL_MapRGB(Icon
->format
, 255, 255, 255));
111 SDL_WM_SetIcon(Icon
, NULL
);
113 if (adresmod
< 0) adresmod
= 0; else if (adresmod
> 10) adresmod
= 10;
114 dblRes
= (adresmod
> 0);
115 if (adresmod
== 10) DIVISOR
= 2.0f
; else DIVISOR
= 1.0f
+(adresmod
/10.0f
);
117 feuLong Flags
= SDL_SWSURFACE
;
119 SDL_ShowCursor(SDL_DISABLE
);
120 Flags
|= SDL_FULLSCREEN
;
123 Screen
= SDL_SetVideoMode(fixVal(NewRes
.X
), fixVal(NewRes
.Y
), /*16*/32, Flags
);
124 if (!Screen
) ABORT("Couldn't set video mode.");
125 if (dblRes
) buildKernel(NewRes
.X
, NewRes
.Y
); else freeKernel();
126 bufc32
= (unsigned char*)realloc(bufc32
, fixVal(NewRes
.X
)*fixVal(NewRes
.Y
)*4);
127 SDL_WM_SetCaption(Title
, 0);
128 globalwindowhandler::Init();
129 DoubleBuffer
= new bitmap(NewRes
);
131 ColorDepth
= 32/*16*/;
135 static inline void toRGB (int* r
, int* g
, int* b
, packcol16 c
) {
136 if (b
) *b
= (c
<<3)&0xff;
137 if (g
) *g
= ((c
>>5)<<2)&0xff;
138 if (r
) *r
= ((c
>>11)<<3)&0xff;
142 static inline packcol16
fromRGB (int r
, int g
, int b
) {
143 if (r
< 0) r
= 0; else if (r
> 255) r
= 255;
144 if (g
< 0) g
= 0; else if (g
> 255) g
= 255;
145 if (b
< 0) b
= 0; else if (b
> 255) b
= 255;
154 void graphics::BlitDBToScreen () {
155 if (SDL_MUSTLOCK(Screen
) && SDL_LockSurface(Screen
) < 0) ABORT("Can't lock screen");
156 const packcol16
*SrcPtr
= DoubleBuffer
->GetImage()[0];
158 const int newx
= fixVal(Res
.X
);
159 const int newy
= fixVal(Res
.Y
);
161 // convert source buffer
162 const packcol16
*sptr
= SrcPtr
;
163 uint32_t *dptr
= (uint32_t*)bufc32
;
164 for (int y
= 0; y
< newy
; ++y
) {
165 for (int x
= 0; x
< newx
; ++x
) {
166 packcol16 c
= *sptr
++;
167 unsigned char b
= (c
<<3)&0xff;
168 unsigned char g
= ((c
>>5)<<2)&0xff;
169 unsigned char r
= ((c
>>11)<<3)&0xff;
170 *dptr
++ = b
|(g
<<8)|(r
<<16);
174 unsigned char *DestPtr
= static_cast<unsigned char*>(Screen
->pixels
);
175 feuLong ScreenYMove
= Screen
->pitch
;
178 if (DIVISOR
!= 2.0f
) {
179 // copy converted buffer used kernel
180 unsigned char *curs
= bufc32
;
182 for (int y
= 0; y
< newy
; ++y
) {
183 uint32_t *dp
= (uint32_t*)DestPtr
;
184 for (int x
= 0; x
< newx
; ++x
) {
186 for (int n
= 0; n
< 3; ++n
) {
187 int c
= lrintf(curs
[i
->sofs
[0]+n
]*i
->frc0
+curs
[i
->sofs
[1]+n
]*i
->frc1
)*i
->yfrc0
+(curs
[i
->sofs
[2]+n
]*i
->frc0
+curs
[i
->sofs
[3]+n
]*i
->frc1
)*i
->yfrc1
;
188 //if (c < 0) c = 0; else if (c > 255) c = 255;
189 //dclr |= (c<<(n*8));
190 dclr
|= ((c
&0xff)|(255-((-(int)(c
< 256))>>24)))<<(n
*8); //K8 WARNING! ABSOLUTELY NON-PORTABLE AND CAUSES UB!
195 DestPtr
+= ScreenYMove
;
198 for (int y
= 0; y
< Res
.Y
; ++y
, DestPtr
+= ScreenYMove
) {
199 uint32_t *s
= (uint32_t*)(bufc32
+y
*(Res
.X
*4));
200 uint32_t *d
= (uint32_t*)(DestPtr
);
201 for (int x
= 0; x
< Res
.X
; ++x
) { *d
++ = *s
; *d
++ = *s
++; }
202 DestPtr
+= ScreenYMove
;
203 memcpy(DestPtr
, bufc32
+y
*(Res
.X
*4), Res
.X
*4*2);
207 for (int y
= 0; y
< Res
.Y
; ++y
, DestPtr
+= ScreenYMove
) {
208 uint32_t *s
= (uint32_t*)(bufc32
+y
*(Res
.X
*4));
209 memcpy(DestPtr
, s
, Res
.X
*4);
212 if (SDL_MUSTLOCK(Screen
)) SDL_UnlockSurface(Screen
);
213 SDL_UpdateRect(Screen
, 0, 0, fixVal(Res
.X
), fixVal(Res
.Y
));
217 void graphics::SwitchMode () {
219 if (Screen
->flags
& SDL_FULLSCREEN
) {
220 SDL_ShowCursor(SDL_ENABLE
);
221 Flags
= SDL_SWSURFACE
;
224 SDL_ShowCursor(SDL_DISABLE
);
225 Flags
= SDL_SWSURFACE
|SDL_FULLSCREEN
;
228 if (SwitchModeHandler
) SwitchModeHandler();
229 Screen
= SDL_SetVideoMode(fixVal(Res
.X
), fixVal(Res
.Y
), ColorDepth
, Flags
);
230 if (!Screen
) ABORT("Couldn't toggle fullscreen mode.");
231 if (dblRes
) buildKernel(Res
.X
, Res
.Y
); else freeKernel();
232 bufc32
= (unsigned char*)realloc(bufc32
, fixVal(Res
.X
)*fixVal(Res
.Y
)*4);
237 void graphics::ReinitMode (sLong adresmod
) {
238 if (adresmod
< 0) adresmod
= 0; else if (adresmod
> 10) adresmod
= 10;
239 dblRes
= (adresmod
> 0);
240 if (adresmod
== 10) DIVISOR
= 2.0f
; else DIVISOR
= 1.0f
+(adresmod
/10.0f
);
244 if (Screen
->flags
&SDL_FULLSCREEN
) {
246 //Flags = SDL_SWSURFACE|SDL_FULLSCREEN;
247 return; // nothing to do here, really
249 Flags
= SDL_SWSURFACE
;
251 Screen
= SDL_SetVideoMode(fixVal(Res
.X
), fixVal(Res
.Y
), ColorDepth
, Flags
);
252 if (dblRes
) buildKernel(Res
.X
, Res
.Y
); else freeKernel();
253 bufc32
= (unsigned char*)realloc(bufc32
, fixVal(Res
.X
)*fixVal(Res
.Y
)*4);
258 void graphics::LoadDefaultFont (cfestring
&FileName
) {
259 DefaultFont
= new rawbitmap(FileName
);