Преглед изворни кода

* graphical cursors are now posiible, however the code is a bit ugly and eats significant amount of resources (up to 15% of my CPU power)

mateuszb пре 18 година
родитељ
комит
6d3a042add
9 измењених фајлова са 354 додато и 5 уклоњено
  1. 237 0
      CCursorHandler.cpp
  2. 30 0
      CCursorHandler.h
  3. 4 0
      CGameInfo.h
  4. 8 1
      CGameInterface.cpp
  5. 13 3
      CMT.cpp
  6. BIN
      CPreGame.cpp
  7. 43 0
      CScreenHandler.cpp
  8. 17 0
      CScreenHandler.h
  9. 2 1
      SDL_Extensions.cpp

+ 237 - 0
CCursorHandler.cpp

@@ -0,0 +1,237 @@
+#include "stdafx.h"
+#include "CCursorHandler.h"
+#include "SDL.h"
+#include "SDL_thread.h"
+#include "CGameInfo.h"
+#include "SDL_framerate.h"
+
+extern SDL_Surface * screen;
+
+/* Creates a new mouse cursor from an XPM */
+
+
+/* XPM */
+static const char *arrow[] = { //no cursor mode
+  /* width height num_colors chars_per_pixel */
+  "    32    32        3            1",
+  /* colors */
+  "X c #000000",
+  ". c #ffffff",
+  "  c None",
+  /* pixels */
+  "                                ",
+  "                                ",
+  "                                ",
+  "                                ",
+  "                                ",
+  "                                ",
+  "                                ",
+  "                                ",
+  "                                ",
+  "                                ",
+  "                                ",
+  "                                ",
+  "                                ",
+  "                                ",
+  "                                ",
+  "                                ",
+  "                                ",
+  "                                ",
+  "                                ",
+  "                                ",
+  "                                ",
+  "                                ",
+  "                                ",
+  "                                ",
+  "                                ",
+  "                                ",
+  "                                ",
+  "                                ",
+  "                                ",
+  "                                ",
+  "                                ",
+  "                                ",
+  "0,0"
+};
+
+/* XPM */
+static const char *arrow2[] = { //normal cursor
+  /* width height num_colors chars_per_pixel */
+  "    32    32        3            1",
+  /* colors */
+  "X c #000000",
+  ". c #ffffff",
+  "  c None",
+  /* pixels */
+  "X                               ",
+  "XX                              ",
+  "X.X                             ",
+  "X..X                            ",
+  "X...X                           ",
+  "X....X                          ",
+  "X.....X                         ",
+  "X......X                        ",
+  "X.......X                       ",
+  "X........X                      ",
+  "X.....XXXXX                     ",
+  "X..X..X                         ",
+  "X.X X..X                        ",
+  "XX  X..X                        ",
+  "X    X..X                       ",
+  "     X..X                       ",
+  "      X..X                      ",
+  "      X..X                      ",
+  "       XX                       ",
+  "                                ",
+  "                                ",
+  "                                ",
+  "                                ",
+  "                                ",
+  "                                ",
+  "                                ",
+  "                                ",
+  "                                ",
+  "                                ",
+  "                                ",
+  "                                ",
+  "                                ",
+  "0,0"
+};
+
+static SDL_Cursor *init_system_cursor(const char *image[])
+{
+  int i, row, col;
+  Uint8 data[4*32];
+  Uint8 mask[4*32];
+  int hot_x, hot_y;
+
+  i = -1;
+  for ( row=0; row<32; ++row ) {
+    for ( col=0; col<32; ++col ) {
+      if ( col % 8 ) {
+        data[i] <<= 1;
+        mask[i] <<= 1;
+      } else {
+        ++i;
+        data[i] = mask[i] = 0;
+      }
+      switch (image[4+row][col]) {
+        case 'X':
+          data[i] |= 0x01;
+          //k[i] |= 0x01;
+          break;
+        case '.':
+          mask[i] |= 0x01;
+          break;
+        case ' ':
+          break;
+      }
+    }
+  }
+  sscanf(image[4+row], "%d,%d", &hot_x, &hot_y);
+  return SDL_CreateCursor(data, mask, 32, 32, hot_x, hot_y);
+}
+
+//int cursorHandlerFunc(void * cursorHandler)
+//{
+//	FPSmanager * cursorFramerateKeeper = new FPSmanager;
+//	SDL_initFramerate(cursorFramerateKeeper);
+//	SDL_setFramerate(cursorFramerateKeeper, 200);
+//
+//	CCursorHandler * ch = (CCursorHandler *) cursorHandler;
+//	while(true)
+//	{
+//		if(ch->xbef!=-1 && ch->ybef!=-1) //restore surface under cursor
+//		{
+//			blitAtWR(ch->behindCur, ch->xbef, ch->ybef);
+//		}
+//		ch->xbef = ch->xpos;
+//		ch->ybef = ch->ypos;
+//		//prepare part of surface to restore
+//		SDL_BlitSurface(screen, &genRect(32, 32, ch->xpos, ch->ypos), ch->behindCur, NULL);
+//		CSDL_Ext::update(ch->behindCur);
+//
+//		//blit cursor
+//		if(ch->curVisible)
+//		{
+//			switch(ch->mode)
+//			{
+//			case 0:
+//				{
+//					break;
+//				}
+//			case 1:
+//				{
+//					break;
+//				}
+//			case 2:
+//				{
+//					blitAtWR(ch->deflt->ourImages[ch->number].bitmap, ch->xpos, ch->ypos);
+//					break;
+//				}
+//			}
+//		}
+//		SDL_framerateDelay(cursorFramerateKeeper);
+//		//SDL_Delay(5); //to avoid great usage of CPU
+//	}
+//	return 0;
+//}
+
+void CCursorHandler::initCursor()
+{
+#if SDL_BYTEORDER == SDL_BIG_ENDIAN
+    int rmask = 0xff000000;
+    int gmask = 0x00ff0000;
+    int bmask = 0x0000ff00;
+    int amask = 0x000000ff;
+#else
+    int rmask = 0x000000ff;
+    int gmask = 0x0000ff00;
+    int bmask = 0x00ff0000;
+    int amask = 0xff000000;
+#endif
+	curVisible = true;
+	xpos = ypos = 0;
+	behindCur = SDL_CreateRGBSurface(SDL_SWSURFACE, 32, 32, 32, rmask, gmask, bmask, amask);
+	xbef = ybef = 0;
+	std::vector<Entry> pom = CGI->spriteh->entries.vectorize();
+	adventure = CGI->spriteh->giveDef("CRADVNTR.DEF");
+	combat = CGI->spriteh->giveDef("CRCOMBAT.DEF");
+	deflt = CGI->spriteh->giveDef("CRDEFLT.DEF");
+	spell = CGI->spriteh->giveDef("CRSPELL.DEF");
+	//SDL_SetCursor(init_system_cursor(arrow));
+	//SDL_Thread * myth = SDL_CreateThread(&cursorHandlerFunc, this);
+}
+
+void CCursorHandler::changeGraphic(int type, int no)
+{
+	mode = type;
+	number = no;
+}
+
+void CCursorHandler::cursorMove(int x, int y)
+{
+	xbef = xpos;
+	ybef = ypos;
+	xpos = x;
+	ypos = y;
+}
+
+void CCursorHandler::hardwareCursor()
+{
+	curVisible = false;
+	SDL_SetCursor(init_system_cursor(arrow2));
+}
+
+void CCursorHandler::hideCursor()
+{
+	curVisible = false;
+	SDL_SetCursor(init_system_cursor(arrow));
+}
+
+void CCursorHandler::showGraphicCursor()
+{
+	curVisible = true;
+	SDL_SetCursor(init_system_cursor(arrow));
+	changeGraphic(0, 0);
+}

+ 30 - 0
CCursorHandler.h

@@ -0,0 +1,30 @@
+#ifndef CCURSORHANDLER_H
+#define CCURSORHANDLER_H
+
+struct SDL_Thread;
+struct CDefHandler;
+struct SDL_Surface;
+
+class CCursorHandler //handles cursor
+{
+public:
+	SDL_Thread * myThread; //thread that updates cursor
+	bool curVisible; //true if cursor is visible
+	int mode, number;
+	SDL_Surface * behindCur;
+	int xbef, ybef; //position of cursor after last move (to restore background)
+
+	CDefHandler * adventure, * combat, * deflt, * spell; //read - only
+	int xpos, ypos; //position of cursor - read only
+	void initCursor(); //inits cursorHandler
+	void showGraphicCursor(); //shows default graphic cursor
+	void cursorMove(int x, int y); //change cursor's positions to (x, y)
+	void changeGraphic(int type, int no); //changes cursor graphic for type type (0 - adventure, 1 - combat, 2 - default, 3 - spellbook) and frame no (not used for type 3)
+	void hideCursor(); //no cursor will be visible
+	void hardwareCursor(); // returns to hardware cursor mode
+	friend int cursorHandlerFunc(void * cursorHandler);
+};
+
+
+
+#endif //CCURSORHANDLER_H

+ 4 - 0
CGameInfo.h

@@ -22,6 +22,8 @@
 #include "mapHandler.h"
 #include "CConsoleHandler.h"
 #include "CPathfinder.h"
+#include "CCursorHandler.h"
+#include "CScreenHandler.h"
 #include "SDL.h"
 
 #include <vector>
@@ -55,6 +57,8 @@ public:
 	CGeneralTextHandler * generaltexth;
 	CConsoleHandler * consoleh;
 	CPathfinder * pathf;
+	CCursorHandler * curh;
+	CScreenHandler * screenh;
 	int localPlayer;
 	std::vector<CGameInterface *> playerint;
 	std::vector<SDL_Color> playerColors;

+ 8 - 1
CGameInterface.cpp

@@ -100,7 +100,8 @@ void CPlayerInterface::yourTurn()
 	//framerate keeper initialized
 	for(;;) // main loop
 	{
-		
+		CGI->screenh->updateScreen();
+
 		LOCPLINT->adventureInt->updateScreen = false;
 		if(SDL_PollEvent(&sEvent))  //wait for event...
 		{
@@ -163,6 +164,12 @@ void CPlayerInterface::yourTurn()
 void CPlayerInterface::handleEvent(SDL_Event *sEvent)
 {
 	current = sEvent;
+
+	if(sEvent->type == SDL_MOUSEMOTION)
+	{
+		CGI->curh->cursorMove(sEvent->motion.x, sEvent->motion.y);
+	}
+
 	if(sEvent->type==SDL_QUIT) 
 		exit(0);
 	else if (sEvent->type==SDL_KEYDOWN)

+ 13 - 3
CMT.cpp

@@ -38,6 +38,8 @@
 #include "CPreGame.h"
 #include "CGeneralTextHandler.h"
 #include "CConsoleHandler.h"
+#include "CCursorHandler.h"
+#include "CScreenHandler.h"
 
 #if defined(MSDOS) || defined(OS2) || defined(WIN32) || defined(__CYGWIN__)
 #  include <fcntl.h>
@@ -56,7 +58,7 @@ const char * NAME = "VCMI 0.3";
    level is supplied, Z_VERSION_ERROR if the version of zlib.h and the
    version of the library linked do not match, or Z_ERRNO if there is
    an error reading or writing the files. */
-SDL_Surface * ekran;
+SDL_Surface * ekran, * screen, * screen2;
 TTF_Font * TNRB16, *TNR, *GEOR13, *GEORXX;
 
 int _tmain(int argc, _TCHAR* argv[])
@@ -70,7 +72,7 @@ int _tmain(int argc, _TCHAR* argv[])
 	int xx=0, yy=0, zz=0;
 	SDL_Event sEvent;
 	srand ( time(NULL) );
-	SDL_Surface *screen, *temp;
+	SDL_Surface *temp;
 	std::vector<SDL_Surface*> Sprites;
 	float i;
 	if(SDL_Init(SDL_INIT_VIDEO|SDL_INIT_TIMER|SDL_INIT_AUDIO/*|SDL_INIT_EVENTTHREAD*/)==0)
@@ -98,7 +100,8 @@ int _tmain(int argc, _TCHAR* argv[])
 			// well, there's no music, but most games don't break without music...
 		}*/
 
-		screen = SDL_SetVideoMode(800,600,24,SDL_SWSURFACE|SDL_DOUBLEBUF/*|SDL_FULLSCREEN*/);
+		screen2 = SDL_SetVideoMode(800,600,24,SDL_SWSURFACE|SDL_DOUBLEBUF/*|SDL_FULLSCREEN*/);
+		screen = SDL_ConvertSurface(screen2, screen2->format, SDL_SWSURFACE);
 		ekran = screen;
 
 		SDL_WM_SetCaption(NAME,""); //set window title
@@ -107,6 +110,7 @@ int _tmain(int argc, _TCHAR* argv[])
 		cgi->consoleh = new CConsoleHandler;
 		cgi->consoleh->runConsole();
 		cgi->mush = mush;
+		cgi->curh = new CCursorHandler;
 
 		THC std::cout<<"Initializing screen, fonts and sound handling: "<<tmh.getDif()<<std::endl;
 		cgi->spriteh = new CLodHandler;
@@ -114,6 +118,12 @@ int _tmain(int argc, _TCHAR* argv[])
 		cgi->bitmaph = new CLodHandler;
 		cgi->bitmaph->init(std::string("Data\\H3bitmap.lod"));
 
+		cgi->curh->initCursor();
+		cgi->curh->showGraphicCursor();
+
+		cgi->screenh = new CScreenHandler;
+		cgi->screenh->initScreen();
+
 		//colors initialization
 		SDL_Color p;
 		p.unused = 0;


+ 43 - 0
CScreenHandler.cpp

@@ -0,0 +1,43 @@
+#include "stdafx.h"
+#include "CScreenHandler.h"
+#include "SDL.h"
+#include "SDL_thread.h"
+#include "SDL_framerate.h"
+#include "SDL_Extensions.h"
+#include "CGameInfo.h"
+
+extern SDL_Surface * screen, * screen2;
+
+void CScreenHandler::initScreen()
+{
+	//myth = SDL_CreateThread(&internalScreenFunc, this);
+}
+
+void CScreenHandler::updateScreen()
+{
+	blitAt(screen, 0, 0, screen2);
+	switch(CGI->curh->mode)
+	{
+	case 0:
+		{
+			blitAt(CGI->curh->adventure->ourImages[CGI->curh->number].bitmap, CGI->curh->xpos, CGI->curh->ypos, screen2);
+			break;
+		}
+	case 1:
+		{
+			blitAt(CGI->curh->combat->ourImages[CGI->curh->number].bitmap, CGI->curh->xpos, CGI->curh->ypos, screen2);
+			break;
+		}
+	case 2:
+		{
+			blitAt(CGI->curh->deflt->ourImages[CGI->curh->number].bitmap, CGI->curh->xpos, CGI->curh->ypos, screen2);
+			break;
+		}
+	case 3:
+		{
+			blitAt(CGI->curh->spell->ourImages[CGI->curh->number].bitmap, CGI->curh->xpos, CGI->curh->ypos, screen2);
+			break;
+		}
+	}
+	CSDL_Ext::update(screen2);
+}

+ 17 - 0
CScreenHandler.h

@@ -0,0 +1,17 @@
+#ifndef CSCREENHANDLER_H
+#define CSCREENHANDLER_H
+
+struct SDL_Thread;
+
+class CScreenHandler
+{
+private:
+	SDL_Thread * myth;
+public:
+	void initScreen();
+	void updateScreen();
+};
+
+
+
+#endif //CSCREENHANDLER_H

+ 2 - 1
SDL_Extensions.cpp

@@ -449,7 +449,8 @@ Uint32 CSDL_Ext::colorToUint32(const SDL_Color * color)
 
 void CSDL_Ext::update(SDL_Surface * what)
 {
-	SDL_UpdateRect(what, 0, 0, what->w, what->h);
+	if(what)
+		SDL_UpdateRect(what, 0, 0, what->w, what->h);
 }
 
 void CSDL_Ext::blueToPlayers(SDL_Surface * sur, int player)