2 Cantaveria - action adventure platform game
3 Copyright (C) 2009 2010 Evan Rinehart
5 This program is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public License
7 as published by the Free Software Foundation; either version 2
8 of the License, or (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to
18 The Free Software Foundation, Inc.
19 51 Franklin Street, Fifth Floor
20 Boston, MA 02110-1301, USA
25 video module is the low level interface to video output.
26 it has several low level functions.
27 * initialize the video system for a certain video mode
28 * load graphics data into the abstract graphics pool
29 * draw a portion of some graphics somewhere on screen
30 * millisecond time delta generator
42 #include <SDL/SDL_opengl.h>
55 static int time_last
; /* initialized by backend_init */
57 int time_now
= SDL_GetTicks();
58 int diff
= time_now
- time_last
;
85 int screen_offset_x
= 0;
86 int screen_offset_y
= 0;
92 /********************/
93 /* drawing routines */
94 /********************/
96 void draw_gfx_raw(int gfxid
, int x
, int y
, int X
, int Y
, int W
, int H
){
98 SDL_Surface
* surf
= gfx
[gfxid
].surf
;
99 SDL_Rect r1
= {X
,Y
,W
,H
};
100 SDL_Rect r2
= {x
,y
,W
,H
};
101 SDL_BlitSurface(surf
,&r1
,video
,&r2
);
104 double w
= gfx
[gfxid
].w
;
105 double h
= gfx
[gfxid
].h
;
106 double X0
= ((double)X
)/w
;
107 double X1
= X0
+ ((double)W
)/w
;
108 double Y0
= ((double)Y
)/h
;
109 double Y1
= Y0
+ ((double)H
)/h
;
111 glBindTexture( GL_TEXTURE_2D
, gfx
[gfxid
].texture
);
120 glVertex3f(x
+W
,y
+H
,0);
128 void draw_test_rect(int x
, int y
, int w
, int h
){
130 SDL_Rect dst
= {x
, y
, w
, h
};
131 SDL_FillRect(video
, &dst
, 0x00ff00ff);
134 glColor3f(1.0, 0.0, 1.0);
137 glVertex3f(x
+w
, y
, 0);
138 glVertex3f(x
+w
, y
+h
, 0);
139 glVertex3f(x
, y
+h
, 0);
141 glColor3f(1.0,1.0,1.0);
145 void draw_gfx(int gfxid
, int x
, int y
, int X
, int Y
, int W
, int H
){
146 draw_gfx_raw(gfxid
, x
+screen_offset_x
, y
+screen_offset_y
, X
, Y
, W
, H
);
151 SDL_FillRect(video
, 0, 0);
154 glClearColor(0.0,0.0,0.0,0.0);
155 glClear( GL_COLOR_BUFFER_BIT
);
161 SDL_UpdateRect(video
,0,0,0,0);
164 SDL_GL_SwapBuffers();
169 /********************/
170 /* graphics loading */
171 /********************/
173 SDL_Surface
* SDL_NewSurface(int w
, int h
){
174 char prefix
[32] = "SDL_NewSurface";
175 SDL_Surface
* tmp
= SDL_CreateRGBSurface(SDL_SRCCOLORKEY
,w
,h
,32,0,0,0,0);
177 out_of_memory(prefix
);
180 SDL_Surface
* surf
= SDL_DisplayFormat(tmp
);
182 out_of_memory(prefix
);
185 SDL_FreeSurface(tmp
);
187 SDL_FillRect(surf
,0,0x00ffffff);
192 void debug_surf(char* msg
, SDL_Surface
* surf
){
195 unsigned char* ptr
= surf
->pixels
;
196 int bpp
= surf
->format
->BytesPerPixel
;
198 for(i
=0; i
<500; i
+=bpp
){
199 printf("%2x %2x %2x %2x\n", ptr
[i
], ptr
[i
+1], ptr
[i
+2], ptr
[i
+3]);
205 SDL_Surface
* load_tga(const char* path
){
206 unsigned char header
[18];
207 reader
* rd
= loader_open(path
);
210 unsigned char parts
[4];
217 error_msg("load_pixmap: error opening file\n");
221 if(loader_read(rd
, header
, 18) < 0){
222 error_msg("load_pixmap: error reading pixmap header\n");
227 w
= header
[12] + (header
[13]<<8);
228 h
= header
[14] + (header
[15]<<8);
233 SDL_Surface
* surf
= SDL_CreateRGBSurface(0,w
,h
,32,
234 0x00ff0000,0x0000ff00,0x000000ff,0xff000000);
236 out_of_memory("load_pixmap");
239 pixels
= surf
->pixels
;
240 mask
= surf
->format
->Amask
;
242 for(i
=0; i
<npix
; i
++){
243 if(loader_read(rd
, parts
, bpp
/8) < 0){
244 error_msg("load_pixmap: error reading pixmap data\n");
246 SDL_FreeSurface(surf
);
251 if(parts
[0] == 0 && parts
[1] == 0 && parts
[2] == 0){
255 pixels
[i
] = parts
[0] | (parts
[1]<<8) | (parts
[2]<<16);
260 if(parts
[0] == 0 && parts
[1] == 0 && parts
[2] == 0){
264 pixels
[i
] = parts
[0] | (parts
[1]<<8) | (parts
[2]<<16);
272 SDL_SetAlpha(surf
, 0, 0);
273 SDL_SetColorKey(surf
, SDL_SRCCOLORKEY
, key
);
274 //debug_surf(filename, surf);
280 int load_gfx(const char* filename
){
284 if(filename
[0] == '\0'){
285 printf("load_gfx: empty path\n");
289 if(gfx_count
== MAX_GFX
){
290 printf("this error can easily be fixed\n");
292 "load_gfx: cannot load any more than %d graphics\n",
297 for(i
=0; i
<gfx_count
; i
++){/*check for already loaded gfx*/
298 if(strcmp(gfx
[i
].filename
, filename
)==0){
303 src
= load_tga(filename
);
305 //fatal_error("load_gfx: failed to load %s\n",filename);
310 gfx
[gfx_count
].filename
= strxcpy(filename
);
311 gfx
[gfx_count
].surf
= src
;
312 gfx
[gfx_count
].w
= src
->w
;
313 gfx
[gfx_count
].h
= src
->h
;
318 glGenTextures( 1, &texture
);
319 glBindTexture( GL_TEXTURE_2D
, texture
);
323 GL_TEXTURE_MIN_FILTER
,
329 GL_TEXTURE_MAG_FILTER
,
350 GL_BGRA
, GL_UNSIGNED_BYTE
,
354 gfx
[gfx_count
].filename
= strxcpy(filename
);
355 gfx
[gfx_count
].texture
= texture
;
356 gfx
[gfx_count
].w
= src
->w
;
357 gfx
[gfx_count
].h
= src
->h
;
359 SDL_FreeSurface(src
);
367 for(i
=2; i
<gfx_count
; i
++){
369 SDL_FreeSurface(gfx
[i
].surf
);
372 glDeleteTextures(1, &(gfx
[i
].texture
));
379 void load_panic_gfx(){
381 printf("load_panic_gfx: must call this before loading graphics\n");
384 load_gfx("gfx/panic.tga");
385 load_gfx("gfx/smallfont.tga");
387 gfx
[0].filename
[0] = 0;
388 gfx
[1].filename
[1] = 0;
402 if(SDL_Init(SDL_INIT_VIDEO
| SDL_INIT_AUDIO
| SDL_INIT_JOYSTICK
)==-1){
403 error_msg("sdl: %s\n",SDL_GetError());
412 void print_version(){
414 "This program is distributed under the terms of the GNU General\n"
415 "Public License (v2) and comes with ABSOLUTELY NO WARRANTY.\n\n"
417 "Send questions, comments, and bugs to evanrinehart@gmail.com\n\n"
420 "1850 Claiborne St\n"
421 "Mandeville, LA 70448\n"
422 "United States of America\n\n"
427 printf("Cantaveria (v%d.%d)\n", VERSION_MAJOR
, VERSION_MINOR
);
428 printf("Copyright 2009 Evan Rinehart\n\n");
429 printf("%s\n", message
);
433 printf("options:\n");
434 printf(" -gl use opengl video mode\n");
435 printf(" -f use fullscreen video mode\n");
436 printf(" -h print this help\n");
437 printf(" -v print version info\n");
440 void parse_options(int argc
, char* argv
[], int* _fullscreen
, int* _gl_flag
){
442 for(i
=0; i
<argc
; i
++){
443 if(!strcmp(argv
[i
], "-gl")){
447 if(!strcmp(argv
[i
], "-f")){
450 if(!strcmp(argv
[i
], "-h") || !strcmp(argv
[i
], "--help")){
454 if(!strcmp(argv
[i
], "-v")){
462 void setup_joysticks(){
463 int N
= SDL_NumJoysticks();
465 boot_msg("sdl: detected %d joysticks\n", N
);
467 if(SDL_JoystickOpen(i
)){
468 boot_msg(" joy%d: %s\n", i
, SDL_JoystickName(i
));
471 boot_msg(" joy%d: %s (failed to open)\n", i
, SDL_JoystickName(i
));
481 SDL_WM_SetCaption("cantaveria","cantaveria");
482 SDL_ShowCursor(SDL_DISABLE
);
483 const SDL_VideoInfo
* vinfo
= SDL_GetVideoInfo();
486 if(fullscreen
&& gl_flag
){
487 screen_w_phys
= vinfo
->current_w
;
488 screen_h_phys
= vinfo
->current_h
;
508 SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER
, 1);
509 //SDL_GL_SetAttribute(SDL_GL_ACCELERATED_VISUAL, 1);
510 //SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, 1);
515 flags
|= SDL_FULLSCREEN
;
520 video
= SDL_SetVideoMode(screen_w_phys
,screen_h_phys
,32,flags
);
522 fatal_error("sdl: %s\n",SDL_GetError());
527 glBlendFunc(GL_SRC_ALPHA
, GL_ONE_MINUS_SRC_ALPHA
);
529 glEnable( GL_TEXTURE_2D
);
530 glClearColor( 0.0f
, 0.0f
, 0.0f
, 0.0f
);
532 glViewport( 0, 0, screen_w_phys
, screen_h_phys
);
534 glClear( GL_COLOR_BUFFER_BIT
);
536 glMatrixMode( GL_PROJECTION
);
539 //glOrtho(0.0f, 240*aspect, 240, 0.0f, -1.0f, 1.0f);
540 //glOrtho(0.0f, 1280.0/3, 800.0/3, 0.0f, -1.0f, 1.0f);
544 if(abs(screen_h_phys
/i
- 240) < min
){
545 min
= screen_h_phys
/i
- 240; n
= i
;
548 double new_w
= ((double)screen_w_phys
)/n
;
549 double new_h
= ((double)screen_h_phys
)/n
;
550 screen_offset_x
= (new_w
-320)/2;
551 screen_offset_y
= (new_h
-240)/2;
552 glOrtho(0.0f
, new_w
, new_h
, 0.0f
, -1.0f
, 1.0f
);
557 glOrtho(0.0f
, 320, 240, 0.0f
, -1.0f
, 1.0f
);
562 glMatrixMode( GL_MODELVIEW
);
570 boot_msg("video:\n");
571 boot_msg(" resolution: %d x %d %s\n",screen_w_phys
,screen_h_phys
,fullscreen
?"fullscreen":"windowed");
572 boot_msg(" pixel dimensions: %d x %d\n",screen_w
,screen_h
);
573 boot_msg(" aspect ratio: %g\n",((double)screen_w_phys
)/screen_h_phys
);
574 boot_msg(" opengl: %s\n",gl_flag
?"yes":"no");
575 boot_msg(" x-offset: %d\n",screen_offset_x
);
576 boot_msg(" y-offset: %d\n",screen_offset_y
);
577 boot_msg(" video on\n");
581 void map_pixel(int mx
, int my
, int *x
, int *y
){
582 *x
= mx
*screen_w
/screen_w_phys
;
583 *y
= my
*screen_h
/screen_h_phys
;
590 void video_init(int argc
, char* argv
[]){
592 parse_options(argc
, argv
, &fullscreen
, &gl_flag
);
595 time_last
= SDL_GetTicks();
599 boot_msg("sdl: quit\n");
607 int update_count
= 0;
612 if(update_count
== 100){
613 fps
= draw_count
* 100 / update_count
;
628 void draw_black_rect(int x
, int y
, int w
, int h
){
630 SDL_Rect r
= {x
, y
, w
, h
};
631 SDL_FillRect(video
, &r
, 0);
635 glColor3f(0.0, 0.0, 0.0);
637 glVertex3f(x
+w
, y
, 0);
638 glVertex3f(x
+w
, y
+h
, 0);
639 glVertex3f(x
, y
+h
, 0);
640 glColor3f(1.0,1.0,1.0);
646 void screen_dimensions(int* w
, int * h
){
654 void gfx_dimensions(int gfxid
, int* w
, int* h
){