lowcpu: reduce the cpu usage by the gameloop.
authorPat Thoyts <patthoyts@users.sourceforge.net>
Tue, 15 Jun 2010 21:03:19 +0000 (22:03 +0100)
committerPat Thoyts <patthoyts@users.sourceforge.net>
Tue, 15 Jun 2010 21:03:19 +0000 (22:03 +0100)
This patch adds support for building using nmake and MSVC on windows and
also modifies the gameloop to drop the cpu usage significantly using a
timer and waiting rather than constantly polling the SDL loop.

Signed-off-by: Pat Thoyts <patthoyts@users.sourceforge.net>
Makefile.vc [new file with mode: 0644]
src/ag.c
src/ag.rc [new file with mode: 0644]
src/dlb.c
src/linked.c
src/sprite.c
src/sprite.h

diff --git a/Makefile.vc b/Makefile.vc
new file mode 100644 (file)
index 0000000..5e2a0c1
--- /dev/null
@@ -0,0 +1,128 @@
+# -*- Makefile -*- 
+#
+#
+# Copyright (C) 2006 Pat Thoyts <patthoyts@users.sourceforge.net>
+#
+#-------------------------------------------------------------------------
+# $Id$
+#-------------------------------------------------------------------------
+
+VERSION=0.2
+
+# You should set SDLDIR to the directory containing your SDL include
+# and lib directories.
+!ifndef SDLDIR
+SDLDIR    =/opt
+!endif
+
+#-------------------------------------------------------------------------
+# There should be no need to edit below this point.
+#-------------------------------------------------------------------------
+
+SRCDIR =src
+
+!ifndef DEBUG
+DEBUG   =0
+!endif
+!ifndef PROFILE
+PROFILE =0
+!endif
+!ifndef SYMBOLS
+SYMBOLS = 0
+!endif
+!ifndef CC
+CC=cl
+!endif
+!ifndef LINK
+LINK=link
+!endif
+
+!if $(DEBUG)
+OUTDIR =Debug
+CFLAGS =-Od -Zi -GZ -MDd -D_DEBUG
+LDFLAGS=-debug:full -debugtype:cv
+!else
+OUTDIR =Release
+!if $(SYMBOLS)
+CFLAGS =-Od -Zi -Op -Gs -MD -DNDEBUG
+LDFLAGS=-debug -opt:ref -opt:icf,3
+!else
+CFLAGS =-O2 -Otip -Gs -MD -DNDEBUG
+LDFLAGS=-release -opt:ref -opt:icf,3
+!endif
+!endif
+
+!if $(PROFILE)
+CFLAGS =$(CFLAGS) -Zi
+LDFLAGS=$(LDFLAGS) -profile -map
+!endif
+
+!if "$(OS)" == "Windows_NT"
+RMDIR = rmdir /s /q >NUL
+!else
+RMDIR = deltree /y
+!endif
+DEL   = del /f /q
+
+TMPDIR =$(OUTDIR)\Objects
+
+CC     =$(CC) -nologo
+LD     =$(LINK) -nologo
+
+CFLAGS =$(CFLAGS) -W3 -YX -Fp$(TMPDIR)^\
+INC    =-I$(SDLDIR)/include
+DEFS   =-DWIN32 -DHAVE_OPENGL -Dmain=SDL_main
+LIBS   =-libpath:$(SDLDIR)/lib SDLmain.lib SDL.lib SDL_mixer.lib kernel32.lib
+LDFLAGS=$(LDFLAGS) -subsystem:windows
+
+OBJS   = \
+        $(TMPDIR)\ag.obj \
+        $(TMPDIR)\dlb.obj \
+        $(TMPDIR)\linked.obj \
+        $(TMPDIR)\sprite.obj \
+       $(TMPDIR)\ag.res
+
+all:    ag
+ag:     setup $(OUTDIR)\ag.exe
+
+$(OUTDIR)\ag.exe: $(OBJS)
+       $(LD) $(LDFLAGS) -out:$@ $** $(LIBS)
+
+.PHONY: all ag
+
+#-------------------------------------------------------------------------
+setup:
+       @if not exist $(OUTDIR) mkdir $(OUTDIR)
+       @if not exist $(TMPDIR) mkdir $(TMPDIR)
+
+clean:
+       @if exist $(TMPDIR)\NUL $(RMDIR) $(TMPDIR) >NUL
+
+realclean: clean
+       @if exist $(OUTDIR)\NUL $(RMDIR) $(OUTDIR) >NUL
+
+.PHONY: setup clean realclean
+#-------------------------------------------------------------------------
+
+.SUFFIXES:.c .cpp .rc
+
+{$(SRCDIR)}.c{$(TMPDIR)}.obj::
+       $(CC) $(CFLAGS) $(DEFS) $(INC) -Fo$(TMPDIR)\ -c @<<
+$<
+<<
+
+{$(SRCDIR)}.cpp{$(TMPDIR)}.obj::
+       $(CC) $(CFLAGS) $(DEFS) $(INC) -Fo$(TMPDIR)\ -c @<<
+$<
+<<
+
+{$(SRCDIR)}.rc{$(TMPDIR)}.res:
+       $(RC) -fo $@ -r -D__WIN32__ \
+       -DCOMMAVERSION=$(VERSION:.=,),0,0 \
+       -DVERSION=\"$(VERSION)\" \
+!if $(DEBUG)
+       -d DEBUG \
+!endif
+       $<
+
+#-------------------------------------------------------------------------
index 0e2ca8e20be70af87a67a54a7a3a7f1e73ea1fcf..c2c13be272b2147dced95b99261a808c8a631566 100755 (executable)
--- a/src/ag.c
+++ b/src/ag.c
@@ -67,6 +67,10 @@ version              who             changes
 #include "sprite.h"
 #include "ag.h"
 
+#ifdef _MSC_VER
+#define snprintf _snprintf
+#endif
+
 //module level variables for game control
 char shuffle[]  = "£££££££";
 char answer[]   = "£££££££";
@@ -341,7 +345,7 @@ void ag(struct node** head, struct dlb_node* dlbHead, char** guess, char** remai
 
 char*  newGuess;
 char*  newRemain;
-int    totalLen=0, guessLen=0, remainLen=0, i;
+int    totalLen=0, guessLen=0, remainLen=0;
 
        // allocate space for our working variables
        guessLen = strlen(*guess);
@@ -365,6 +369,7 @@ int    totalLen=0, guessLen=0, remainLen=0, i;
        }
 
        if (strlen(newRemain)){
+        size_t i;
                ag(&(*head), dlbHead, &newGuess, &newRemain);
 
                for (i=totalLen-1;i>0;i--){
@@ -867,7 +872,7 @@ void updateScore(SDL_Surface* screen){
 // we'll display the total Score, this is the game score
 
 char buffer [256];
-int i;
+size_t i;
 SDL_Rect fromrect, torect, blankRect;
 
        blankRect.x = SCORE_WIDTH * 11;
@@ -1176,8 +1181,8 @@ int numSwaps;
 
        while(thisLetter != NULL){
                if (thisLetter->box == SHUFFLE){
-                       thisLetter->toX = (whereinstr(shufflePos, thisLetter->index+1) * (GAME_LETTER_WIDTH + GAME_LETTER_SPACE)) + BOX_START_X;
-                       thisLetter->index = whereinstr(shufflePos, thisLetter->index+1);
+                       thisLetter->toX = (whereinstr(shufflePos, (char)(thisLetter->index+1)) * (GAME_LETTER_WIDTH + GAME_LETTER_SPACE)) + BOX_START_X;
+                       thisLetter->index = whereinstr(shufflePos, (char)(thisLetter->index+1));
                }
 
                thisLetter = thisLetter->next;
@@ -1487,7 +1492,7 @@ int i;
        // show background
        ShowBMP("images/background.bmp",screen, 0,0);
 
-       destroyLetters(&(*letters));
+       destroyLetters(letters);
 
        guess = malloc(sizeof(char)*50);
        remain = malloc(sizeof(char)*50);
@@ -1552,8 +1557,17 @@ int i;
 
 }
 
-
-
+static Uint32
+TimerCallback(Uint32 interval, void *param)
+{
+    SDL_UserEvent evt;
+    evt.type = SDL_USEREVENT;
+    evt.code = 0;
+    evt.data1 = 0;
+    evt.data2 = 0;
+    SDL_PushEvent((SDL_Event *)&evt);
+    return 0;
+}
 
 /***********************************************************
 synopsis: a big while loop that runs the full length of the
@@ -1591,7 +1605,10 @@ void gameLoop(struct node** head, struct dlb_node* dlbHead, SDL_Surface* screen,
 int done=0;
 SDL_Event event;
 int timeNow;
+SDL_TimerID timer;
+int timer_delay = 20;
 
+    timer = SDL_AddTimer(timer_delay, TimerCallback, NULL);
        // main game loop
        while (!done){
 
@@ -1669,13 +1686,11 @@ int timeNow;
                        //displayLetters(screen);
 
                        shuffleRemaining = 0;
-
-
                }
 
                if (clearGuess){
                        // clear the guess;
-                       if (clearWord(&(*letters)) > 0)
+                       if (clearWord(letters) > 0)
                                Mix_PlayChannel(-1, getSound("clear"),0);
 
                        clearGuess = 0;
@@ -1685,22 +1700,25 @@ int timeNow;
                        done=1;
                }
 
-               while (SDL_PollEvent(&event))
+               while (SDL_WaitEvent(&event))
                {
-                       switch (event.type) {
-                               case SDL_MOUSEBUTTONDOWN:
-                                       clickDetect(event.button.button, event.button.x, event.button.y, screen, *head, &(*letters));
-                                       break;
-
-                               case SDL_KEYUP:
-                                       handleKeyboardEvent(&event, *head, &(*letters));
-                                        break;
-                                case SDL_QUIT:
-                                       done=1;
+                       if (event.type == SDL_USEREVENT) {
+                timer_delay = anySpritesMoving(letters) ? 10 : 100;
+                moveSprites(&screen, letters, letterSpeed);
+                timer = SDL_AddTimer(timer_delay, TimerCallback, NULL);
+                break;
+            } else if (event.type == SDL_MOUSEBUTTONDOWN) {
+                clickDetect(event.button.button, event.button.x,
+                            event.button.y, screen, *head, letters);
+            } else if (event.type == SDL_KEYUP) {
+                handleKeyboardEvent(&event, *head, letters);
+            } else if (event.type == SDL_QUIT) {
+                done = 1;
+                break;
                        }
-                }
-               moveSprites(&screen, &(*letters), letterSpeed);
+            moveSprites(&screen, letters, letterSpeed);
         }
+    }
 }
 
 
@@ -1724,10 +1742,17 @@ SDL_Surface *screen;
 struct sprite* letters = NULL;
 //pthread_t audio;
 
+       // buffer sounds
+       int audio_rate = MIX_DEFAULT_FREQUENCY;
+       Uint16 audio_format = AUDIO_S16;
+       int audio_channels = 1;
+       int audio_buffers = 256;
+
+
        // seed the random generator
        srand(time(NULL));
 
-       if (SDL_Init(SDL_INIT_AUDIO|SDL_INIT_VIDEO) < 0){
+       if (SDL_Init(SDL_INIT_AUDIO|SDL_INIT_VIDEO|SDL_INIT_TIMER) < 0){
                fprintf(stderr, "Unable to init SDL: %s\n", SDL_GetError());
                exit(1);
        }
@@ -1743,12 +1768,6 @@ struct sprite* letters = NULL;
 
        SDL_WM_SetCaption("Anagramarama", "ANAGRAMARAMA");
 
-       // buffer sounds
-       int audio_rate = MIX_DEFAULT_FREQUENCY;
-       Uint16 audio_format = AUDIO_S16;
-       int audio_channels = 1;
-       int audio_buffers = 256;
-
        if(Mix_OpenAudio(audio_rate, audio_format, audio_channels, audio_buffers)){
                printf("unable to open audio!\n");
                exit(1);
diff --git a/src/ag.rc b/src/ag.rc
new file mode 100644 (file)
index 0000000..8563d59
--- /dev/null
+++ b/src/ag.rc
@@ -0,0 +1,38 @@
+// ag.rc - 
+//
+// There is no need to modify this file.
+//
+
+#include <winver.h>
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION   COMMAVERSION
+ PRODUCTVERSION        COMMAVERSION
+ FILEFLAGSMASK 0x3fL
+#ifdef DEBUG
+ FILEFLAGS     VS_FF_DEBUG
+#else
+ FILEFLAGS     0x0L
+#endif
+ FILEOS                VOS__WINDOWS32
+ FILETYPE      VFT_DLL
+ FILESUBTYPE   0x0L
+BEGIN
+    BLOCK "StringFileInfo"
+    BEGIN
+        BLOCK "040904b0"
+        BEGIN
+            VALUE "FileDescription",  "Anagramarama " VERSION "\0"
+            VALUE "OriginalFilename", "ag" VERSION ".exe\0"
+            VALUE "CompanyName",      "GPL\0"
+            VALUE "FileVersion",      VERSION "\0"
+            VALUE "LegalCopyright",   "Copyright \251 2003 Colm Gallagher\0"
+            VALUE "ProductName",      "Anagramarama " VERSION "\0"
+            VALUE "ProductVersion",   VERSION "\0"
+        END
+    END
+    BLOCK "VarFileInfo"
+    BEGIN
+        VALUE "Translation", 0x409, 1200
+    END
+END
index 029aacfc43b3a142a46bb83e612e961398f5ba03..3277378ee930d57d673eb90e1f86154ac65dbb4c 100755 (executable)
--- a/src/dlb.c
+++ b/src/dlb.c
@@ -45,7 +45,7 @@ void dlb_push(struct dlb_node** dlbHead, char* thisWord){
 // add a new word to the dictionary
 struct dlb_node* current = *dlbHead;
 struct dlb_node* previous = NULL;
-int i=0;
+size_t i=0;
 char letter;
 int child = 0;
 int sibling = 0;
@@ -119,7 +119,7 @@ int dlb_lookup(struct dlb_node* dlbHead, char* thisWord){
 
 struct dlb_node* current = dlbHead;
 struct dlb_node* previous = NULL;
-int i=0;
+size_t i=0;
 char letter;
 int retval = 0;
 
index 3bb020452abc5aa8aa4650b3e67f03b83d59be55..45fd8d2a2dad374a94abb030aee1c4c859a21803 100755 (executable)
@@ -155,7 +155,7 @@ int duplicate = 0;
 
        if (!duplicate){
                len = strlen(anagram+1);
-               newNode->anagram = malloc(sizeof(char)*len);
+               newNode->anagram = malloc(sizeof(char)*(len + 1));
                strcpy(newNode->anagram, anagram);
                newNode->length = len + 1;
                newNode->found = 0;
index 051703ae8dc61a8da34348941ea0a3e8cd0de03b..39c40fcc14125541d0399045e3297f7644cf70f0 100755 (executable)
@@ -69,6 +69,24 @@ SDL_Rect rect;
        SDL_BlitSurface((*movie)->replace, NULL, *screen, &rect);
 }
 
+/********************************************************************/
+static int
+isSpriteMoving(struct sprite *p)
+{
+    /* returns true if this sprite needs to move */
+       return (p->y != p->toY) ||  (p->x != p->toX);
+}
+int
+anySpritesMoving(struct sprite **letters)
+{
+    struct sprite *current;
+    for (current = *letters; current != NULL; current = current->next) {
+        if (isSpriteMoving(current))
+            return 1;
+    }
+    return 0;
+}
+
 /********************************************************************/
 void moveSprite(SDL_Surface** screen, struct sprite** movie, int letterSpeed){
 
index c54c2c115b6965113163319cd21d12a5aad06f1c..14aefbe54779fa2c54c3ddea95bbc8fa062b9698 100755 (executable)
@@ -49,3 +49,4 @@ int nextBlankPosition(int box, int* index);
 //void clickDetect(int button, int x, int y, SDL_Surface *screen, struct sprite** letters);
 void destroyLetters(struct sprite** letters);
 //void buildLetters(struct sprite** letters, SDL_Surface* screen);
+int anySpritesMoving(struct sprite **letters);