original 1.0.1 release
[xwelltris.git] / src / sdl / sdlwellengine.cxx
blobbae02e0674622222482299a59bb977ea3fe961a6
1 // docm_prefix(///)
2 /****************************************************************************
3 * Copyright (C) 2002-2003 by Leo Khramov
4 * email: leo@xnc.dubna.su
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 ****************************************************************************/
16 // $Id: sdlwellengine.cxx,v 1.5 2003/02/21 11:40:33 leo Exp $
18 /// module description
19 /// This module contains methods of class SDLWellEngine which implements SDL calls
20 /// for the game. So this is SDL dependent part. It receives Events,
21 /// make convertions, many initions and calls.
23 #include "version.h"
24 #include "globals.h"
25 #include "sdlwellengine.h"
26 #include "sdlwellimagefont.h"
27 #include "sdlwellinput.h"
28 #include "sdlwelldrawing.h"
29 #include "SDL_image.h"
30 #include "sdl_gfxprimitives.h"
31 #include "commonfuncs.h"
33 //Colors for welltris pieces and grid (x color names)
34 static Uint8 game_color_names[MAX_GAME_COLORS][3] =
36 /* 0 "Red" */ { 255, 0, 0},
37 /* 1 "Green" */ { 0,255, 0},
38 /* 2 "Blue" */ { 0, 0,255},
39 /* 3 "Yellow" */ { 255,255, 0},
40 /* 4 "Magenta" */ { 255, 0,255},
41 /* 5 "Cyan" */ { 0,255,255},
42 /* 6 "FireBrick" */ { 178, 34, 34},
43 /* 7 "SpringGreen", */ { 0,255,127},
44 /* 8 "CornflowerBlue" */ { 100,149,237},
45 /* 9 "Khaki" */ { 240,230,140},
46 /*10 "Plum" */ { 221,160,221},
47 /*11 "Violet" */ { 238,130,238},
48 /*12 "DarkTurquoise" */ { 0,206,209},
49 /*13 "Gold" */ { 255,215, 0},
50 /*14 "Orchid" */ { 218,112,214},
51 /*15 "Turquoise" */ { 64,224,208},
52 /*16 "Orange" */ { 255,165, 0},
53 /*17 "OrangeRed" */ { 255, 69, 0},
54 /*18 "VioletRed" */ { 208, 32,144},
55 /*19 "BlueViolet" */ { 138, 43,226},
56 /*20 "SeaGreen" */ { 46,139, 87},
57 /*21 "Pink" */ { 255,192,203},
58 /*22 "ForestGreen" */ { 34,139, 34},
59 /*23 "SkyBlue" */ { 135,206,235},
60 /*24 "Coral" */ { 255,127, 80},
61 /*25 "Wheat" */ { 245,222,179},
62 /*26 "GoldenRod" */ { 218,165, 32},
63 /*27 "IndianRed" */ { 205, 92, 92},
64 /*28 "SpringGreen" */ { 0,255,127},
65 /*29 "CornflowerBlue" */ { 100,149,237},
66 /*30 "Thistle" */ { 216,191,216},
67 /*31 "Aquamarine" */ { 127,255,212},
68 /*32 "CadetBlue" */ { 95,158,160},
69 /*33 "LightSteelBlue" */ { 176,196,222},
70 /*34 "NavyBlue" */ { 0, 0,128},
71 /*35 "SteelBlue" */ { 70,130,180},
72 /*36 "YellowGreen" */ { 154,205, 50},
73 /*37 "DarkViolet" */ { 148, 0,211},
74 /*38 "MediumSeaGreen" */ { 60,179,113},
75 /*39 "DarkSlateGray" */ { 47, 79, 79},
76 /*40 "LightGray" */ { 211,211,211},
77 /*41 "MediumVioletRed" */ { 199, 21,133},
78 /*42 "Sienna" */ { 160, 82, 45},
79 /*43 "MediumAquamarine"*/ { 102,205,170},
80 /*44 "MediumBlue" */ { 0, 0,205},
81 /*45 "Navy" */ { 0, 0,128},
82 /*46 "DarkOliveGreen" */ { 85,107, 47},
83 /*47 "DarkGreen" */ { 0,100, 0},
84 /*48 "DimGray" */ { 105,105,105},
85 /*49 "Tan" */ { 210,180,140},
86 /*50 "MediumTurquoise" */ { 72,209,204},
87 /*51 "DarkSlateBlue" */ { 72, 61,139},
88 /*52 "Maroon" */ { 176, 48, 96},
89 /*53 "Gray" */ { 190,190,190},
90 /*54 "#303030" */ {0x30,0x30,0x30},
92 /*55 "Black" */ { 0, 0, 0},
93 /*56 "#00aa00" */ { 0,0xaa, 0},
94 /*56 "#00ee00" */ { 0,0xee, 0},
95 /*57 "#aa0000" */ {0xaa, 0, 0},
96 /*58 "#aaaaaa" */ {0xaa,0xaa,0xaa},
97 /*59 "#cccc00" */ {0xcc,0xcc, 0},
98 /*60 "#eeee00" */ {0xee,0xee, 0}
101 const unsigned long TIMESTEP=5000l;
102 const int KEY_TICKS=5;
103 const int FIRST_KEY_TICKS=25;
104 //===========================================================================
105 /// global new_well_engine(argc,argv)
106 /// Creates new WellEngine object, SDL realization (create SDLWellEngine)
107 /// tags new_well_engine
108 WellEngine* new_well_engine(int argc, char** argv)
110 return new SDLWellEngine(argc,argv);
113 //===========================================================================
114 /// global SDLWellEngine(argc,argv)
115 /// Constructor of class that incupsulates work with SDL window
116 /// This class must always be allocated through 'new'
117 /// args
118 /// +argc: number of commanline args
119 /// +argv: command line args
120 /// tags SDLWellEngine
121 SDLWellEngine::SDLWellEngine(int argc, char** argv):WellEngine(argc,argv)
123 if( SDL_Init(SDL_INIT_VIDEO) < 0 )
125 fprintf(stderr, "Unable to init SDL: %s\n", SDL_GetError());
126 exit(1);
128 init_mainwindow(argc,argv);
129 init_colors();
130 load_images();
131 SDL_EnableUNICODE(1);
132 bg_image=0;
135 //===========================================================================
136 /// global SDLWellEngine(argc,argv)
137 /// Destructor of class that incupsulates work with SDL window
138 /// tags SDLWellEngine
139 SDLWellEngine::~SDLWellEngine()
141 SDL_Quit();
144 //===========================================================================
145 /// global init_mainwindow(argc,argv)
146 /// create main game window and all other stuff around it
147 /// tags SDLWellEngine
148 void SDLWellEngine::init_mainwindow(int argc,char **argv)
150 mainw = SDL_SetVideoMode(mainl, mainh, 16,
151 SDL_ANYFORMAT);
152 if( mainw == 0 )
154 fprintf(stderr, "Unable to set %dx%dx16 video: %s\n",mainl, mainh,
155 SDL_GetError());
156 SDL_Quit();
157 exit(1);
159 dbgprintf(("VIDEO_INIT: Set 800x600x%d video mode\n", mainw->format->BitsPerPixel));
162 //===========================================================================
163 /// global show_main()
164 /// show main window
165 /// tags SDLWellEngine
166 void SDLWellEngine::show_main()
168 SDL_UpdateRect(mainw, 0,0, mainl, mainh);
172 void SDLWellEngine::set_key_event(SDL_Event& event)
174 key_event=event;
175 key_event_got=true;
176 process_event_for_all(wEvent(eKeyPress,&key_event));
177 key_ticks=FIRST_KEY_TICKS;
180 void SDLWellEngine::reset_key_event()
182 key_event_got=false;
185 void SDLWellEngine::process_key_event()
187 if(key_ticks)
189 key_ticks--;
190 return;
192 process_event_for_all(wEvent(eKeyPress,&key_event));
193 key_ticks=KEY_TICKS;
197 //===========================================================================
198 /// global event_loop()
199 /// main event loop - process all events and make game moves
200 /// tags SDLWellEngine
201 void SDLWellEngine::event_loop()
203 SDL_Event event;
204 MouseEvent mev;
205 done_loop_var=false;
206 key_event_got=false;
207 dbgprintf(("Entered in event_loop\n"));
209 while(!done_loop_var)
211 while(SDL_PollEvent(&event))
213 switch (event.type)
215 case SDL_VIDEOEXPOSE:
216 dbgprintf(("Got expose event - processing\n"));
217 process_event_for_all(wEvent(eExpose,&event));
218 break;
219 case SDL_KEYDOWN:
220 dbgprintf(("The '%s' key was pressed!\n",
221 SDL_GetKeyName(event.key.keysym.sym)));
222 set_key_event(event);
223 key_event=event;
224 key_event_got=true;
225 break;
227 case SDL_KEYUP:
228 reset_key_event();
229 break;
231 case SDL_MOUSEMOTION:
232 mev.mx=event.motion.x;
233 mev.my=event.motion.y;
234 mev.bstate=event.motion.state==SDL_BUTTON_LEFT ? But1Press : But2Press;
235 process_event_for_all(wEvent(eMouseMove,&mev));
236 dbgprintf(("Mouse moved by to (%d,%d) with state: %d\n",
237 event.motion.x, event.motion.y, event.motion.state));
238 break;
239 case SDL_MOUSEBUTTONDOWN:
240 dbgprintf(("MouseButtonPress event\n"));
241 mev.mx=event.button.x;
242 mev.my=event.button.y;
243 mev.bstate=event.button.button==SDL_BUTTON_LEFT ? But1Press : But2Press;
244 process_event_for_all(wEvent(eMousePress,&mev));
245 break;
246 case SDL_QUIT:
247 done_loop_var=true;
250 if(key_event_got)
251 process_key_event();
252 udelay(TIMESTEP);
253 process_time_event();
258 //===========================================================================
259 /// global wait_for_timers()
260 /// calculate delay and wait for events and timers
261 /// tags SDLWellEngine
262 int SDLWellEngine::wait_for_timers()
264 return 0;
267 //===========================================================================
268 /// global load_image(Images id, char* name)
269 /// Load image into memory and register it with given id for use
270 /// tags SDLWellEngine
271 bool SDLWellEngine::load_image(Images id, char* name)
273 char buf[L_MAXPATH];
275 if(id>=MAX_IMAGES)
276 return false;
278 find_full_path_for_file(name,buf);
279 pics[id]=IMG_Load(buf);
280 images[id].id=id;
281 dbgprintf(("Loaded image: %s\n",buf));
282 return true;
286 //===========================================================================
287 /// global set_main_background_image(Images id)
288 /// set image with given id to background of main window
289 /// tags SDLWellEngine
290 void SDLWellEngine::set_main_background_image(Images id)
292 SDL_Rect dest;
293 if(images[id].id!=imNone)
295 dest.x = 0;
296 dest.y = 0;
297 dest.w = pics[id]->w;
298 dest.h = pics[id]->h;
299 SDL_BlitSurface(pics[id], 0, mainw, &dest);
300 /* Update the changed portion of the screen */
301 SDL_UpdateRects(mainw, 1, &dest);
302 bg_image=pics[id];
306 //===========================================================================
307 /// local init_colors()
308 /// allocate all nessesary colors
309 /// tags SDLWellEngine
310 void SDLWellEngine::init_colors()
312 int i;
313 for(i=0;i<MAX_GAME_COLORS;i++)
315 game_colors[i]=SDL_MapRGBA(mainw->format,
316 game_color_names[i][0],
317 game_color_names[i][1],
318 game_color_names[i][2], 255);
319 game_RGBA[i*4+0]=game_color_names[i][0];
320 game_RGBA[i*4+1]=game_color_names[i][1];
321 game_RGBA[i*4+2]=game_color_names[i][2];
322 game_RGBA[i*4+3]=255;
327 //===========================================================================
328 /// global new_well_image_font()
329 /// creates image font object - version for SDL Window
330 /// tags SDLWellEngine
331 WellImageFont* SDLWellEngine::new_well_image_font(Images id,
332 unsigned int ifl,
333 unsigned int ifh,
334 int idx, int idy)
336 return new SDLWellImageFont(id,ifl,ifh,idx,idy);
339 //===========================================================================
340 /// global new_well_input(char*)
341 /// creates new input object - version for SDL Window
342 /// tags SDLWellEngine
343 WellInput* SDLWellEngine::new_well_input(char* name)
345 return new SDLWellInput(name);
348 //===========================================================================
349 /// global new_well_drawing_engine()
350 /// creates drawing engine for well board - version for SDL Window
351 /// tags SDLWellEngine
352 WellDrawingEngine* SDLWellEngine::new_well_drawing_engine()
354 return new SDLWellDrawingEngine(this);
357 //===========================================================================
358 /// global udelay(int msec)
359 /// Portable delay :)
360 /// tags XWellEngine
361 void SDLWellEngine::udelay(int msec)
363 SDL_Delay(msec/1000);
366 //===========================================================================
367 /// global screen_copy(Geo*)
368 /// copy part of image to the screen
369 /// tags SDLWellEngine
370 void SDLWellEngine::screen_copy(Geo *pgeo)
372 SDL_Rect src,dest;
373 if(pgeo->im==imNone)
375 screen_clear(pgeo);
376 return;
378 src.x=pgeo->fromx;
379 src.y=pgeo->fromy;
380 src.w=dest.w=pgeo->l;
381 src.h=dest.h=pgeo->h;
382 dest.x=pgeo->tox;
383 dest.y=pgeo->toy;
385 SDL_BlitSurface(pics[pgeo->im],
386 &src, mainw, &dest);
387 SDL_UpdateRects(mainw, 1, &dest);
390 //===========================================================================
391 /// global screen_clear(Geo*)
392 /// clear part of screen
393 /// tags SDLWellEngine
394 void SDLWellEngine::screen_clear(Geo *pgeo)
396 SDL_Rect dest;
397 dest.x=pgeo->tox;
398 dest.y=pgeo->toy;
399 dest.w=pgeo->l;
400 dest.h=pgeo->h;
402 if(!bg_image)
403 SDL_FillRect(mainw, &dest, game_colors[BackColor]);
404 else
405 SDL_BlitSurface(bg_image, &dest, mainw, &dest);
407 SDL_UpdateRects(mainw, 1, &dest);