From 3e029639df23ad221b3e94525703b52c4f90ff57 Mon Sep 17 00:00:00 2001
From: Sonicadvance1 <sonicadvance1@gmail.com>
Date: Fri, 29 Aug 2008 09:55:17 +0000
Subject: [PATCH] Removed jpeg dependency in GL plugin, added Rumble to Linux
 nJoy. and reverted my accidental Dolphin ini file

git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@379 8ced0084-cf51-0410-be5f-012b33b47a6e
---
 Binary/linux/Dolphin.ini                      |   4 +-
 .../Plugins/Plugin_VideoOGL/Src/Globals.cpp   | 145 +-----------------
 Source/Plugins/Plugin_VideoOGL/Src/Globals.h  |   1 -
 Source/Plugins/Plugin_VideoOGL/Src/Render.cpp |   2 -
 Source/Plugins/Plugin_VideoOGL/Src/SConscript |   2 +-
 .../Plugin_VideoOGL/Src/TextureMngr.cpp       |   2 -
 Source/Plugins/Plugin_nJoy_SDL/Src/nJoy.cpp   |  66 ++++++++
 Source/Plugins/Plugin_nJoy_SDL/Src/nJoy.h     |   3 +
 8 files changed, 72 insertions(+), 153 deletions(-)

diff --git a/Binary/linux/Dolphin.ini b/Binary/linux/Dolphin.ini
index dfa4016e05..6c6743c349 100644
--- a/Binary/linux/Dolphin.ini
+++ b/Binary/linux/Dolphin.ini
@@ -1,7 +1,6 @@
 [General]
 LastFilename = 
-GCMPathes = 1
-GCMPath0 = /home/ryan/Desktop/GCISOS
+GCMPathes = 0
 [Core]
 GFXPlugin = Plugins/libzeroogl.so
 DSPPlugin = Plugins/libdsphle.so
@@ -9,7 +8,6 @@ PadPlugin = Plugins/libPlugin_nJoy_SDL.so
 HLEBios = True
 UseDynarec = False
 UseDualCore = False
-Throttle = True
 LockThreads = True
 DefaultGCM = 
 OptimizeQuantizers = True
diff --git a/Source/Plugins/Plugin_VideoOGL/Src/Globals.cpp b/Source/Plugins/Plugin_VideoOGL/Src/Globals.cpp
index fa62133927..76814e79d9 100644
--- a/Source/Plugins/Plugin_VideoOGL/Src/Globals.cpp
+++ b/Source/Plugins/Plugin_VideoOGL/Src/Globals.cpp
@@ -114,149 +114,6 @@ void Config::Save()
     iniFile.Save("gfx_opengl.ini");
 }
 
-#ifdef _M_IX86
-
-extern "C" {
-#ifdef _WIN32
-#define XMD_H
-#undef FAR
-#define HAVE_BOOLEAN
-#endif
-
-#include <jpeglib.h>
-}
-
-bool SaveJPEG(const char* filename, int image_width, int image_height, const void* pdata, int quality)
-{
-    u8* image_buffer = new u8[image_width * image_height * 3];
-    u8* psrc = (u8*)pdata;
-    
-    // input data is rgba format, so convert to rgb
-    u8* p = image_buffer;
-    for(int i = 0; i < image_height; ++i) {
-        for(int j = 0; j < image_width; ++j) {
-            p[0] = psrc[0];
-            p[1] = psrc[1];
-            p[2] = psrc[2];
-            p += 3;
-            psrc += 4;
-        }
-    }
-
-    /* This struct contains the JPEG compression parameters and pointers to
-    * working space (which is allocated as needed by the JPEG library).
-    * It is possible to have several such structures, representing multiple
-    * compression/decompression processes, in existence at once.  We refer
-    * to any one struct (and its associated working data) as a "JPEG object".
-    */
-    struct jpeg_compress_struct cinfo;
-    /* This struct represents a JPEG error handler.  It is declared separately
-    * because applications often want to supply a specialized error handler
-    * (see the second half of this file for an example).  But here we just
-    * take the easy way out and use the standard error handler, which will
-    * print a message on stderr and call exit() if compression fails.
-    * Note that this struct must live as long as the main JPEG parameter
-    * struct, to avoid dangling-pointer problems.
-    */
-    struct jpeg_error_mgr jerr;
-    /* More stuff */
-    FILE * outfile;     /* target file */
-    JSAMPROW row_pointer[1];    /* pointer to JSAMPLE row[s] */
-    int row_stride;     /* physical row width in image buffer */
-
-    /* Step 1: allocate and initialize JPEG compression object */
-
-    /* We have to set up the error handler first, in case the initialization
-    * step fails.  (Unlikely, but it could happen if you are out of memory.)
-    * This routine fills in the contents of struct jerr, and returns jerr's
-    * address which we place into the link field in cinfo.
-    */
-    cinfo.err = jpeg_std_error(&jerr);
-    /* Now we can initialize the JPEG compression object. */
-    jpeg_create_compress(&cinfo);
-
-    /* Step 2: specify data destination (eg, a file) */
-    /* Note: steps 2 and 3 can be done in either order. */
-
-    /* Here we use the library-supplied code to send compressed data to a
-    * stdio stream.  You can also write your own code to do something else.
-    * VERY IMPORTANT: use "b" option to fopen() if you are on a machine that
-    * requires it in order to write binary files.
-    */
-    if ((outfile = fopen(filename, "wb")) == NULL) {
-    fprintf(stderr, "can't open %s\n", filename);
-    exit(1);
-    }
-    jpeg_stdio_dest(&cinfo, outfile);
-
-    /* Step 3: set parameters for compression */
-
-    /* First we supply a description of the input image.
-    * Four fields of the cinfo struct must be filled in:
-    */
-    cinfo.image_width = image_width;    /* image width and height, in pixels */
-    cinfo.image_height = image_height;
-    cinfo.input_components = 3;     /* # of color components per pixel */
-    cinfo.in_color_space = JCS_RGB;     /* colorspace of input image */
-    /* Now use the library's routine to set default compression parameters.
-    * (You must set at least cinfo.in_color_space before calling this,
-    * since the defaults depend on the source color space.)
-    */
-    jpeg_set_defaults(&cinfo);
-    /* Now you can set any non-default parameters you wish to.
-    * Here we just illustrate the use of quality (quantization table) scaling:
-    */
-    jpeg_set_quality(&cinfo, quality, TRUE /* limit to baseline-JPEG values */);
-
-    /* Step 4: Start compressor */
-
-    /* TRUE ensures that we will write a complete interchange-JPEG file.
-    * Pass TRUE unless you are very sure of what you're doing.
-    */
-    jpeg_start_compress(&cinfo, TRUE);
-
-    /* Step 5: while (scan lines remain to be written) */
-    /*           jpeg_write_scanlines(...); */
-
-    /* Here we use the library's state variable cinfo.next_scanline as the
-    * loop counter, so that we don't have to keep track ourselves.
-    * To keep things simple, we pass one scanline per call; you can pass
-    * more if you wish, though.
-    */
-    row_stride = image_width * 3;   /* JSAMPLEs per row in image_buffer */
-
-    while (cinfo.next_scanline < cinfo.image_height) {
-    /* jpeg_write_scanlines expects an array of pointers to scanlines.
-        * Here the array is only one element long, but you could pass
-        * more than one scanline at a time if that's more convenient.
-        */
-    row_pointer[0] = & image_buffer[cinfo.next_scanline * row_stride];
-    (void) jpeg_write_scanlines(&cinfo, row_pointer, 1);
-    }
-
-    /* Step 6: Finish compression */
-
-    jpeg_finish_compress(&cinfo);
-    /* After finish_compress, we can close the output file. */
-    fclose(outfile);
-
-    /* Step 7: release JPEG compression object */
-
-    /* This is an important step since it will release a good deal of memory. */
-    jpeg_destroy_compress(&cinfo);
-
-    delete image_buffer;
-    /* And we're done! */
-    return true;
-}
-
-#else
-bool SaveJPEG(const char* filename, int image_width, int image_height, const void* pdata, int quality)
-{
-	return false;
-}
-#endif
-
 #if defined(_MSC_VER)
 #pragma pack(push, 1)
 #endif
@@ -321,7 +178,7 @@ bool SaveTexture(const char* filename, u32 textarget, u32 tex, int width, int he
         return false;
     }
 
-    return SaveTGA(filename, width, height, &data[0]);//SaveJPEG(filename, width, height, &data[0], 70);
+    return SaveTGA(filename, width, height, &data[0]);
 }
 
 ////////////////////
diff --git a/Source/Plugins/Plugin_VideoOGL/Src/Globals.h b/Source/Plugins/Plugin_VideoOGL/Src/Globals.h
index a175648852..1271868a34 100644
--- a/Source/Plugins/Plugin_VideoOGL/Src/Globals.h
+++ b/Source/Plugins/Plugin_VideoOGL/Src/Globals.h
@@ -229,7 +229,6 @@ void SysMessage(const char *fmt, ...);
 void HandleGLError();
 
 void InitLUTs();
-bool SaveJPEG(const char* filename, int image_width, int image_height, const void* pdata, int quality);
 bool SaveTGA(const char* filename, int width, int height, void* pdata);
 bool SaveTexture(const char* filename, u32 textarget, u32 tex, int width, int height);
 
diff --git a/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp b/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp
index 268f92faa6..579caf6e39 100644
--- a/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp
+++ b/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp
@@ -796,8 +796,6 @@ bool Renderer::SaveRenderTarget(const char* filename, int jpeg)
             memcpy(&data[(nBackbufferHeight-i-1)*nBackbufferWidth], &scanline[0], nBackbufferWidth*4);
         }
     }
-
-    if (jpeg) return SaveJPEG(filename, nBackbufferWidth, nBackbufferHeight, &data[0], 70);
     
     return SaveTGA(filename, nBackbufferWidth, nBackbufferHeight, &data[0]);
 }
diff --git a/Source/Plugins/Plugin_VideoOGL/Src/SConscript b/Source/Plugins/Plugin_VideoOGL/Src/SConscript
index 8803aa2c55..592ce89682 100644
--- a/Source/Plugins/Plugin_VideoOGL/Src/SConscript
+++ b/Source/Plugins/Plugin_VideoOGL/Src/SConscript
@@ -30,7 +30,7 @@ linkFlags = [
 	'`wx-config --libs`',
 	]
 libs = [
-	'videocommon', 'common', 'GLEW', 'jpeg',
+	'videocommon', 'common', 'GLEW',
 	]
 if sys.platform == 'darwin':
 	platform = 'mac'
diff --git a/Source/Plugins/Plugin_VideoOGL/Src/TextureMngr.cpp b/Source/Plugins/Plugin_VideoOGL/Src/TextureMngr.cpp
index dd2e1be8b6..4b24a6ca05 100644
--- a/Source/Plugins/Plugin_VideoOGL/Src/TextureMngr.cpp
+++ b/Source/Plugins/Plugin_VideoOGL/Src/TextureMngr.cpp
@@ -318,8 +318,6 @@ void TextureMngr::CopyRenderTargetToTexture(u32 address, bool bFromZBuffer, bool
     entry.frameCount = frameCount;
     
     int mult = bScaleByHalf?2:1;
-   // int wmulti = (abs(source->right-source->left)/mult+7)&~7;
-    //int hmulti = (abs(source->bottom-source->top)/mult+7)&~7;
     int w = (abs(source->right-source->left)/mult+7)&~7;
     int h = (abs(source->bottom-source->top)/mult+7)&~7;
 
diff --git a/Source/Plugins/Plugin_nJoy_SDL/Src/nJoy.cpp b/Source/Plugins/Plugin_nJoy_SDL/Src/nJoy.cpp
index f27b4dea91..99fdc8b0bf 100644
--- a/Source/Plugins/Plugin_nJoy_SDL/Src/nJoy.cpp
+++ b/Source/Plugins/Plugin_nJoy_SDL/Src/nJoy.cpp
@@ -70,6 +70,11 @@ BOOL CALLBACK EnumAxesCallback(const DIDEVICEOBJECTINSTANCE* pdidoi, VOID* pCont
 HRESULT SetDeviceForcesXY();
 #endif
 
+#else
+	int fd;
+	char device_file_name[64];
+	struct ff_effect effect;
+	bool CanRumble = false;
 #endif
 
 //////////////////////////////////////////////////////////////////////////////////////////
@@ -292,6 +297,8 @@ void PAD_Shutdown()
 	#ifdef USE_RUMBLE_DINPUT_HACK
 	FreeDirectInput();
 	#endif
+	#else
+	close(fd);
 	#endif
 }
 
@@ -429,6 +436,38 @@ void PAD_GetStatus(BYTE _numPAD, SPADStatus* _pPADStatus)
 			g_pEffect->Start(1, 0);
 	}
 	#endif
+	#else
+	if(!fd)
+	{
+		sprintf(device_file_name, "/dev/input/event%d", joysticks[_numPAD].eventnum); //TODO: Make dynamic //
+
+		/* Open device */
+		fd = open(device_file_name, O_RDWR);
+		if (fd == -1) {
+			perror("Open device file");
+			//Something wrong, probably permissions, just return now
+			return;
+		}
+		int n_effects = 0;
+		if (ioctl(fd, EVIOCGEFFECTS, &n_effects) == -1) {
+			perror("Ioctl number of effects");
+		}
+		if(n_effects > 0)
+			CanRumble = true;
+		else
+			return; // Return since we can't do any effects
+		/* a strong rumbling effect */
+		effect.type = FF_RUMBLE;
+		effect.id = -1;
+		effect.u.rumble.strong_magnitude = 0x8000;
+		effect.u.rumble.weak_magnitude = 0;
+		effect.replay.length = 5000; // Set to 5 seconds, if a Game needs more for a single rumble event, it is dumb and must be a demo
+		effect.replay.delay = 0;
+		if (ioctl(fd, EVIOCSFF, &effect) == -1) {
+			perror("Upload effect");
+			CanRumble = false; //We have effects but it doesn't support the rumble we are using. This is basic rumble, should work for most
+		}
+	}
 	#endif
 }
 
@@ -467,6 +506,31 @@ void PAD_Rumble(BYTE _numPAD, unsigned int _uType, unsigned int _uStrength)
 		SetDeviceForcesXY();
 	}
 	#endif
+	#else
+	struct input_event event;
+	if(CanRumble)
+	{
+		if (_uType == 1)
+		{
+			event.type = EV_FF;
+			event.code = effect.id;
+			event.value = 1;
+			if (write(fd, (const void*) &event, sizeof(event)) == -1) {
+				perror("Play effect");
+				exit(1);
+			}
+		}
+		if ((_uType == 0) || (_uType == 2))
+		{
+			event.type = EV_FF;
+			event.code =  effect.id;
+			event.value = 0;
+			if (write(fd, (const void*) &event, sizeof(event)) == -1) {
+				perror("Stop effect");
+				exit(1);
+			}
+		}
+	}
 	#endif
 }
 
@@ -671,6 +735,7 @@ void SaveConfig()
 		file.Set(SectionName, "halfpress", joysticks[i].halfpress);
 		file.Set(SectionName, "joy_id", joysticks[i].ID);
 		file.Set(SectionName, "controllertype", joysticks[i].controllertype);
+		file.Set(SectionName, "eventnum", joysticks[i].eventnum);
 	}
 
 	file.Save("nJoy.ini");
@@ -710,6 +775,7 @@ void LoadConfig()
 		file.Get(SectionName, "halfpress", &joysticks[i].halfpress, 6);	
 		file.Get(SectionName, "joy_id", &joysticks[i].ID, 0);
 		file.Get(SectionName, "controllertype", &joysticks[i].controllertype, 0);
+		file.Get(SectionName, "eventnum", &joysticks[i].eventnum, 0);
 	}
 }
 
diff --git a/Source/Plugins/Plugin_nJoy_SDL/Src/nJoy.h b/Source/Plugins/Plugin_nJoy_SDL/Src/nJoy.h
index dae6f8be08..5c22f160ec 100644
--- a/Source/Plugins/Plugin_nJoy_SDL/Src/nJoy.h
+++ b/Source/Plugins/Plugin_nJoy_SDL/Src/nJoy.h
@@ -57,6 +57,8 @@
 #define SLEEP(x) Sleep(x)
 #else
 #include <unistd.h>
+#include <sys/ioctl.h>
+#include <linux/input.h>
 #define SLEEP(x) usleep(x*1000)
 #endif
 
@@ -117,6 +119,7 @@ struct CONTROLLER_MAPPING{	// GC PAD MAPPING
 	int halfpress;			// Halfpress... you know, like not fully pressed ;)...
 	int ID;					// SDL joystick device ID
 	int controllertype;		// Joystick, Joystick no hat or a keyboard (perhaps a mouse later)
+	int eventnum;			// Linux Event Number, Can't be found dynamically yet
 };
 
 struct CONTROLLER_INFO{		// CONNECTED WINDOWS DEVICES INFO