From: <or...@us...> - 2008-08-25 09:47:40
|
Revision: 327 http://open2x.svn.sourceforge.net/open2x/?rev=327&view=rev Author: orkie Date: 2008-08-25 09:47:45 +0000 (Mon, 25 Aug 2008) Log Message: ----------- Please start using libs-new Modified Paths: -------------- trunk/libs-new/sdl/sdl/SDL-1.2.13/configure.in trunk/libs-new/sdl/sdl/SDL-1.2.13/src/video/gp2x/SDL_gp2xevents.c trunk/libs-new/sdl/sdl/SDL-1.2.13/src/video/gp2x/SDL_gp2xmouse.c trunk/libs-new/sdl/sdl/SDL-1.2.13/src/video/gp2x/SDL_gp2xvideo.c trunk/libs-new/sdl/sdl/SDL-1.2.13/src/video/gp2x/SDL_gp2xvideo.h trunk/libs-new/sdl/sdl/SDL-1.2.13/src/video/gp2x/gp2x_tslib.c Added Paths: ----------- trunk/libs-new/sdl/sdl/SDL-1.2.13/README.GP2X trunk/libs-new/sdl/sdl/SDL-1.2.13/include/SDL_gp2x.h trunk/libs-new/sdl/sdl/SDL-1.2.13/src/video/gp2x/SDL_gp2xyuv.c trunk/libs-new/sdl/sdl/SDL-1.2.13/src/video/gp2x/SDL_gp2xyuv_c.h Added: trunk/libs-new/sdl/sdl/SDL-1.2.13/README.GP2X =================================================================== --- trunk/libs-new/sdl/sdl/SDL-1.2.13/README.GP2X (rev 0) +++ trunk/libs-new/sdl/sdl/SDL-1.2.13/README.GP2X 2008-08-25 09:47:45 UTC (rev 327) @@ -0,0 +1,295 @@ +---------------------------------------- +|Open2x - SDL Port to use GP2X hardware| +---------------------------------------- + +Version: SDL for the GP2X (Based on SDL 1.2.13) +----------------------------------------------- + +Using the official http://www.libsdl.org/ 1.2.13 release as a basis this +release aims to add advanced support for the GP2X handheld console/computer. + +This libary is part of the Open2x libs project. + + http://wiki.open2x.org/open2x/wiki/index.php?title=Libraries + +Changes from stock SDL +---------------------- + +Added hardware support, made as a seperate video driver rather than +extending fbcon driver. +Added ability to scale display surface to full-screen. +Fixed X & Y buttons. +Added (partial) hardware cursor support +Added regions - user-definable areas of the physical display to show. +Added support for non-scaled displays that are smaller than native resolution. +Added single USB mouse support. +Added USB joystick and keyboard support. +Added backlight & CPU speed adjustments. +Added preliminary TV-out control. +Added option to allow extra 16MB gfx memory +Added Touchscreen support for F200. +Added YUV support (very limited). + +TODO: + + Cursor support may be flaky on interlaced TV modes. + Better control of gfx memory. + Lots more + +Building: +--------- + +You can just install SDL onto most popular GP2X development kits by +downloading and installing a recent prebuilt library package + + http://wiki.open2x.org/open2x/wiki/index.php?title=Prebuilt_Library_Packages + +You can also build and install all the libraries by running ./open2x-libs.sh +from the root libs/ folder. Please review the README.OPEN2X in that folder for +more info. + +Lastly, you can just build SDL on its own using a configure flag something +like what is shown below. + +./configure --prefix=$LIB_ROOT --host=$HOST --disable-shared --enable-video-gp2x --enable-video-fbcon=no + + +Using: +------ + +This is SDL and can be used just like any other SDL build. + +**** +** Limitations of GP2X video driver +**** + +The primary surface (as set by SDL_SetVideoMode) is limited to 8 or 16 bit. +24 and 32 bit modes are NOT supported, driver will use 16bit instead. +SetVideoMode also forces SDL_HWSURFACE + +WARNING: Loading images with IMG_Load(filename) will create SWSURFACES, to +convert them to HWSURFACES do this: + + img_temp = IMG_Load("my_image.png"); + img = SDL_DisplayFormat(img_temp); + SDL_FreeSurface(img_temp); + +Screen sizes can be between 64x64 and 1024x768 inclusive, but the width must +be a multiple of 8 (legacy), width will be rounded up if need be. +The primary surface will be visually expanded or shrunk to fill either the +LCD or TV. The scaler is coarse only, no nice bilinear filtering. + +HWSURFACE to HWSURFACE blits are accelerated and ASYNCHRONOUS, SDL_BlitSurface +will return as soon as it has set the blit up, you MUST lock the surface if +you want to be sure the blit has taken place. + +==== +== SWSURFACE to HWSURFACE blits have moderate acceleration and SDL_BlitSurface +== will return when the blit is finished, although locking the surface is still +== required to ensure the blitter flushes its cache. +=== +== NOTE: My driver supports it, but SDL seems to not call my blit routine if +== the source surface is SWSURFACE. Will look into it later. +==== + +The harware cursor is capable of colour (although only 2), but is 24bit +regardless of the display surface. It can also alpha-blend it's fore- and +background colours at different levels, each ranging from 0=transparent to +15=opaque. + + +**** +** Additional non-standard SDL functions, GP2X specific. +** +** These are defined in the non-standard SDL_gp2x.h +**** + +//// +int SDL_GP2X_GetPhysicalScreenSize(SDL_Rect *size); + + Fills size->w and size->h with dimensions of the current screen, + LCD : 320x240 + NTSC : 720x480 + PAL : 720x576 + Returns + 0 for progressive (LCD) + 1 for interlaced (NTSC & PAL) + -1 if SDL_Init hasn't been called yet + +//// +void SDL_GP2X_Display(SDL_Rect *area); + + Sets the hardware scaler to show requested area of primary surface as + fullscreen. The scaler does not physically alter the surface, it just + affects how the surface will appear on-screen. This allows you to pan + around a surface larger than the screen, and/or zoom in/out. + You cannot zoom out further than having the full surface on-screen. + + area->x and area->y set which pixel of the primary surface will appear at + the top-left corner of the display, + area->w and area->h set the width and height of the area to fill the display. + +//// +void SDL_GP2X_MiniDisplay(int x, int y); + + Similar to the above function, but does not scale and blanks the borders. + Only really useful if your videomode is less than 320x240. Gives rise to + possible small speed increase as the display hardware doesn't access + memory in the borders. Region 1 (see SDL_GP2X_DefineRegion below) area is + set to {x, y, x+videomode_width-1, y+videomodeheight-1}. + The x & y values are where the top-left corner of you screen will placed + on the display. e.g. for a 200x200 videomode centred in the middle of the + display you'd use x=60 y=20 + NO checking is done to make sure your screen fits! + +//// +void SDL_GP2X_SetCursorColour(SDL_Cursor *cursor + int b_red, b_green, b_blue, b_alpha, + int f_red, f_green, f_blue, f_alpha); + + Sets the background and foreground colours of the hardware cursor. + SDL assumes black and white for all cursors, this lets you choose + your own colours for each cursor. Cursor colours are full 24bit, each + component wraps instead of clamping (so if you try setting red to 257 + you'll actually get 1 etc.) + Also, the background and foreground colours have seperate levels of + alpha-blending (0=transparent -> 15=opaque). Again, the values wrap. + +//// +void SDL_GP2X_DefineRegion(int region, SDL_Rect *area); + + Allows you to define regions (1-4) that will be visible. + By default region 1 is set to fullscreen (apart from when using MiniDisplay). + Regions work by defining rectangles of the display that the video hardware + will show. Think of it like painting your LCD black and for each region + you use, scrape the paint off for that rectangle. + Region areas are in hardware coordinates, 0x0 is the top-left, + 319x239 is bottom-right regardless of size and position of your surface. + +//// +void SDL_GP2X_ActivateRegion(int region, int activate); + + After defining regions above, use this to switch individual regions + on (activate = 1) or off (activate=0). + By default only region 1 is active. + There is a fifth region, region 5, but this is fullscreen only and hence + not available to SDL_GP2X_DefineRegion(). + +//// +void SDL_SYS_JoystickGp2xSys(SDL_Joystick joystick, int command); + + joystick _must_ be the value returned by SDL_JoystickOpen(0). This is + because this function relies on data that is stored in the joystick + structure of the internal joystick. To be doing anything on the GP2X + you'll more than likely be wanting access to the buttons anyway. + The values you can pass as the command are as follows: + BACK_LIGHT_OFF - Switches the backlight off ;) + BACK_LIGHT_ON - Switches the backlight back on. + BATT_LED_OFF - Switches the red battery light on. + BATT_LED_ON - Switches the red battery light off. + FCLK_200 - Runs the CPU at 200 MHz. + FCLK_166 - Runs the CPU at 166 MHz. + FCLK_133 - Runs the CPU at 133 MHz. + FCLK_100 - Runs the CPU at 100 MHz. + FCLK_78 - Runs the CPU at 78 MHz. + FCLK_64 - Runs the CPU at 64 MHz. + The following is allowed, but I've just checked the soruce for /dev/gpio to + see what speed it corresponded to and found that it doesn't actually do + anything. + FCLK_DEFAULT - Runs the CPU at it's default speed. + +//// +void SDL_GP2X_TV(int state); + + Allows user control of TV-Out. + state = 0 Internal screen on - TV off. + state = 1 TV on - internal screen off + +//// +int SDL_GP2X_TVMode(int mode); + + Allows switching of the TV-out chip's mode. + Where mode is one of :- + DISPLAY_LCD, + DISPLAY_MONITOR, + DISPLAY_TV_NTSC, + DISPLAY_TV_PAL, + DISPLAY_TV_GAME_NTSC; + +//// +void SDL_GP2X_TVAdjust(int direction); + + Allows adjustment of TV position. + Where direction is one of :- + TV_POS_LEFT, + TV_POS_RIGHT, + TV_POS_UP, + TV_POS_DOWN; + +//// +void SDL_GP2X_AllowGfxMemory(char *start, int size); + + Allows the user to make regions of upper memory available to SDL. + Call this function AFTER SDL_Init() but before SDL_SetVideoMode(). + + ** Partial implementation + ** The values are currently ignored, calling this function will enable + ** SDL to use the first 16MB of upper memory in addition to the standard + ** 5MB frame buffer. Gfx memory will be 21MB + +//// +void SDL_GP2X_DenyGfxMemory(char *start, int size); + + Allows the user to make regions of upper memory unavailable to SDL. + Call this function AFTER SDL_Init() but before SDL_SetVideoMode(). + + ** Partial implementation + ** The values are currently ignored, calling this function will prevent + ** SDL from using the first 16MB of upper memory. + ** Gfx memory will be the standard 5MB frame buffer. + +//// +void SDL_GP2X_VSync(); + + Waits for the current frame to be fully displayed. + Not needed for double buffered screens. + +//// +void *SDL_GP2X_PhysAddress(SDL_Surface *surface); + + Returns the address of the surface's bitmap for use by the 940. + Only the hardware and 940 can use the address returned by this function. + This function is only valid for hardware surfaces that have been locked + with SDL_LockSurface(). + + ** NOTE ** + You must lock the surface first, and after you unlock the surface + the pointer that was returned must be considered invalid. + + If the function returns NULL then SDL_GetError() will return one of + the following :- + + "Invalid or unlocked surface" - You passed either a null pointer or + the surface wasn't locked. + + "PhysAddress() only valid for hardware surfaces" + - You tried getting the address of a + software surface which the 940 cannot + access. + +************************************************************* +** The following functions are implemented, but not tested ** +************************************************************* + +//// +void SDL_GP2X_SetMonoColours(int background, int foreground); + **** + ** untested function + **** + When blitting a 1bpp surface, this sets what colour the 0s and 1s will + be translated into. Useful for drawing fonts. + This is a global setting, not per-surface. + +------------------------------------- + +The Open2x Project Modified: trunk/libs-new/sdl/sdl/SDL-1.2.13/configure.in =================================================================== --- trunk/libs-new/sdl/sdl/SDL-1.2.13/configure.in 2008-08-19 11:43:56 UTC (rev 326) +++ trunk/libs-new/sdl/sdl/SDL-1.2.13/configure.in 2008-08-25 09:47:45 UTC (rev 327) @@ -2271,7 +2271,7 @@ CheckX11 CheckNANOX CheckFBCON - CheckGP2XVideo + CheckGP2XVideo CheckDirectFB CheckPS2GS CheckGGI Added: trunk/libs-new/sdl/sdl/SDL-1.2.13/include/SDL_gp2x.h =================================================================== --- trunk/libs-new/sdl/sdl/SDL-1.2.13/include/SDL_gp2x.h (rev 0) +++ trunk/libs-new/sdl/sdl/SDL-1.2.13/include/SDL_gp2x.h 2008-08-25 09:47:45 UTC (rev 327) @@ -0,0 +1,54 @@ +/* + * Non-standard SDL header. + * + * This header gives access to a few extra features of the GP2X hardware + * that I added to the video driver. + */ + +#ifndef SDL_GP2X__H +#define SDL_GP2X__H + +#ifdef __cplusplus +extern "C" { +#endif + +#define GP2X_MOUSE_NONE 0 +#define GP2X_MOUSE_STD 1 +#define GP2X_MOUSE_TOUCHSCREEN 2 + + +void SDL_GP2X_SetMonoColours(int background, int foreground); +int SDL_GP2X_GetPhysicalScreenSize(SDL_Rect *size); +void SDL_GP2X_Display(SDL_Rect *area); +void SDL_GP2X_InitializeCursor(); +void SDL_GP2X_SetCursorColour(WMcursor *wcursor, + int bred, int bgreen, int bblue, int balpha, + int fred, int fgreen, int fblue, int falpha); +void SDL_GP2X_DefineRegion(int region, SDL_Rect *area); +void SDL_GP2X_ActivateRegion(int region, int activate); +void SDL_GP2X_MiniDisplay(int x, int y); +void SDL_GP2X_WaitForBlitter(); + +int SDL_GP2X_TV(int state); +int SDL_GP2X_TVMode(int mode); +void SDL_GP2X_TVAdjust(int direction); + +void SDL_GP2X_AllowGfxMemory(char *start, int size); +void SDL_GP2X_DenyGfxMemory(char *start, int size); + +void SDL_GP2X_VSync(); + +// Return a hardware surface's bitmap address for use by the 940 +// Surface has to be SDL_HWSURFACE *and* SDL_LockSurface()ed +// When you unlock the surface the address you got from here *must* +// be considered invalid. +void *SDL_GP2X_PhysAddress(SDL_Surface *surface); + +// Query GP2X mouse type +int SDL_GP2X_MouseType(); + +#ifdef __cplusplus +} +#endif + +#endif Modified: trunk/libs-new/sdl/sdl/SDL-1.2.13/src/video/gp2x/SDL_gp2xevents.c =================================================================== --- trunk/libs-new/sdl/sdl/SDL-1.2.13/src/video/gp2x/SDL_gp2xevents.c 2008-08-19 11:43:56 UTC (rev 326) +++ trunk/libs-new/sdl/sdl/SDL-1.2.13/src/video/gp2x/SDL_gp2xevents.c 2008-08-25 09:47:45 UTC (rev 327) @@ -51,12 +51,9 @@ #include "SDL.h" #include "SDL_mutex.h" - -//senquack - had to add path prefixes to all of these to get this to compile -#include "../../events/SDL_sysevents.h" #include "../SDL_sysvideo.h" #include "../../events/SDL_events_c.h" - +#include "../../events/SDL_sysevents.h" #include "SDL_gp2xvideo.h" #include "SDL_gp2xevents_c.h" #include "SDL_gp2xkeys.h" @@ -211,8 +208,7 @@ if (mousedev == NULL) { /* FIXME someday... allow multiple mice in this driver */ static const char * const ps2mice[] = { - "/dev/input/mouse/0", NULL - // "/dev/input/mouse/0", "/dev/usbmouse", "/dev/psaux", NULL + "/dev/input/mouse/0", "/dev/usbmouse", "/dev/psaux", NULL }; /* Now try to use a modern PS/2 mouse */ for (i=0; (this->hidden->mouse_fd < 0) && ps2mice[i]; ++i ) { Modified: trunk/libs-new/sdl/sdl/SDL-1.2.13/src/video/gp2x/SDL_gp2xmouse.c =================================================================== --- trunk/libs-new/sdl/sdl/SDL-1.2.13/src/video/gp2x/SDL_gp2xmouse.c 2008-08-19 11:43:56 UTC (rev 326) +++ trunk/libs-new/sdl/sdl/SDL-1.2.13/src/video/gp2x/SDL_gp2xmouse.c 2008-08-25 09:47:45 UTC (rev 327) @@ -30,7 +30,6 @@ #include "SDL_error.h" #include "SDL_mouse.h" -//senquack - had to add path prefix: #include "../../events/SDL_events_c.h" #include "SDL_gp2xmouse_c.h" Modified: trunk/libs-new/sdl/sdl/SDL-1.2.13/src/video/gp2x/SDL_gp2xvideo.c =================================================================== --- trunk/libs-new/sdl/sdl/SDL-1.2.13/src/video/gp2x/SDL_gp2xvideo.c 2008-08-19 11:43:56 UTC (rev 326) +++ trunk/libs-new/sdl/sdl/SDL-1.2.13/src/video/gp2x/SDL_gp2xvideo.c 2008-08-25 09:47:45 UTC (rev 327) @@ -44,7 +44,6 @@ #include "SDL_video.h" #include "SDL_mouse.h" -//senquack - had to add path prefixes to all of these to get this to compile #include "../SDL_sysvideo.h" #include "../SDL_pixels_c.h" #include "../../events/SDL_events_c.h" @@ -52,6 +51,7 @@ #include "SDL_gp2xvideo.h" #include "SDL_gp2xevents_c.h" #include "SDL_gp2xmouse_c.h" +#include "SDL_gp2xyuv_c.h" #include "mmsp2_regs.h" #define GP2XVID_DRIVER_NAME "GP2X" @@ -189,7 +189,7 @@ device->VideoInit = GP2X_VideoInit; device->ListModes = GP2X_ListModes; device->SetVideoMode = GP2X_SetVideoMode; - device->CreateYUVOverlay = NULL; + device->CreateYUVOverlay = GP2X_CreateYUVOverlay; device->SetColors = GP2X_SetColors; device->UpdateRects = GP2X_UpdateRects; device->VideoQuit = GP2X_VideoQuit; @@ -257,7 +257,7 @@ return -1; } data->vmem = mmap(NULL, GP2X_VIDEO_MEM_SIZE, PROT_READ|PROT_WRITE, - MAP_SHARED, data->memory_fd, 0x2000000); + MAP_SHARED, data->memory_fd, GP2X_UPPER_MEM_START); if (data->vmem == (char *)-1) { SDL_SetError("Unable to get video memory"); data->vmem = NULL; @@ -812,11 +812,14 @@ GP2X_DummyBlit(this); do {} while (data->fio[MESGSTATUS] & MESG_BUSY); + // Waiting for vblank can be used by the YUV stuff too, so I moved it into a separate function + GP2X_WaitVBlank(data); + // wait for vblank to start, choose transition type by polarity - if (data->vsync_polarity) - do {} while ((data->io[GPIOB_PINLVL] & GPIOB_VSYNC)); - else - do {} while (!(data->io[GPIOB_PINLVL] & GPIOB_VSYNC)); +// if (data->vsync_polarity) +// do {} while ((data->io[GPIOB_PINLVL] & GPIOB_VSYNC)); +// else +// do {} while (!(data->io[GPIOB_PINLVL] & GPIOB_VSYNC)); // Wait to be on even field (non-interlaced always returns 0) // do {} while (data->io[SC_STATUS] & SC_DISP_FIELD); @@ -1560,7 +1563,7 @@ { SDL_PrivateVideoData *data = current_video->hidden; char *end = start + size; - char *block = (char*)0x2000000; // Start of upper memory + char *block = (char*)GP2X_UPPER_MEM_START; // Start of upper memory data->allow_scratch_memory = 1; } Modified: trunk/libs-new/sdl/sdl/SDL-1.2.13/src/video/gp2x/SDL_gp2xvideo.h =================================================================== --- trunk/libs-new/sdl/sdl/SDL-1.2.13/src/video/gp2x/SDL_gp2xvideo.h 2008-08-19 11:43:56 UTC (rev 326) +++ trunk/libs-new/sdl/sdl/SDL-1.2.13/src/video/gp2x/SDL_gp2xvideo.h 2008-08-25 09:47:45 UTC (rev 327) @@ -50,6 +50,9 @@ #define GP2X_SCREEN_OFFSET 0 //0x1101000 +// This is used in both gp2xvideo and gp2xyuv, so I put it here to make maintenance easier +#define GP2X_UPPER_MEM_START 0x2000000 + // Number of native modes supported #define SDL_NUMMODES 8 Added: trunk/libs-new/sdl/sdl/SDL-1.2.13/src/video/gp2x/SDL_gp2xyuv.c =================================================================== --- trunk/libs-new/sdl/sdl/SDL-1.2.13/src/video/gp2x/SDL_gp2xyuv.c (rev 0) +++ trunk/libs-new/sdl/sdl/SDL-1.2.13/src/video/gp2x/SDL_gp2xyuv.c 2008-08-25 09:47:45 UTC (rev 327) @@ -0,0 +1,373 @@ +/* + SDL - Simple DirectMedia Layer - SDL_gp2xyuv.c extension + Copyright (C) 2007 Matt Ownby + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +/* This is the GP2X implementation of YUV video overlays */ + +#include <stdlib.h> +#include <string.h> +#include <fcntl.h> // for open +#include <sys/mman.h> // for mmap +#include <unistd.h> // for close + +#ifdef GP2X_DEBUG + #include <assert.h> // for self testing ... +#endif // GP2X_DEBUG + +#include "SDL_error.h" +#include "SDL_video.h" +#include "SDL_gp2xyuv_c.h" +#include "../SDL_yuvfuncs.h" +#include "mmsp2_regs.h" +//#include "arm_colorconv.h" + +/* The functions used to manipulate software video overlays */ +static struct private_yuvhwfuncs gp2x_yuvfuncs = +{ + GP2X_LockYUVOverlay, + GP2X_UnlockYUVOverlay, + GP2X_DisplayYUVOverlay, + GP2X_FreeYUVOverlay +}; + +struct private_yuvhwdata +{ + Uint8 *YUVBuf[2]; // we will have two buffers, a front and back (double buffered) + unsigned int GP2XAddr[2]; // the yuv buffer address from the gp2x's perspective + unsigned int uBackBuf; // which buffer is currently the back buffer (0 or 1) + unsigned int uBufSize; // how big the YUVBuf buffers are (in bytes) + SDL_Rect rctLast; // the last rectangle we used for displaying (so we know when to rescale/change coordinates) + Uint16 u16PixelWidth; // value stored for MLC_VLA_TP_PXW register + + /* These are just so we don't have to allocate them separately */ + Uint16 pitches[3]; + Uint8 *planes[3]; +}; + +// These are the registers (currently) modified by this code; +// They are in this array so we can restore them to their previous state after the overlay is destroyed. +const unsigned int g_pTouchedRegs[] = +{ + MLC_OVLAY_CNTR, + 0x2882 >> 1, + 0x2884 >> 1, + 0x2886 >> 1, + 0x288A >> 1, + 0x288C >> 1, + 0x2892 >> 1, + 0x2896 >> 1, + 0x2898 >> 1, + 0x289A >> 1, + 0x289C >> 1, + 0x289E >> 1, + 0x28A0 >> 1, + 0x28A2 >> 1, + 0x28A4 >> 1, + 0x28A6 >> 1, + 0x28C0 >> 1, + 0x28C2 >> 1 +}; + +const unsigned int TOUCHEDREGS_COUNT = sizeof(g_pTouchedRegs) / sizeof(unsigned int); + +// where we save the regs (compiler wouldn't let me use TOUCHEDREGS_COUNT in array) +static unsigned short g_pu16SavedRegs[sizeof(g_pTouchedRegs) / sizeof(unsigned int)]; + +#ifdef GP2X_DEBUG + // to test whether saving and restoring the regs is working + void *g_pRegTester = NULL; +#endif // GP2X_DEBUG + +// saves or restores registers that are used by the YUV code depending on 'iSave' +static void GP2X_SaveRestoreRegs(_THIS, int iSave) +{ + SDL_PrivateVideoData *data = this->hidden; + unsigned int u = 0; + + for (u = 0; u < TOUCHEDREGS_COUNT; u++) + { + // if we're saving the registers + if (iSave) + { + g_pu16SavedRegs[u] = data->io[g_pTouchedRegs[u]]; + } + // else we're restoring the registers + else + { + data->io[g_pTouchedRegs[u]] = g_pu16SavedRegs[u]; + } + } +} + +static int GP2X_SetupYUV(_THIS, int width, int height, Uint32 format, struct private_yuvhwdata *hwdata) +{ + int iSuccess = 0; + SDL_PrivateVideoData *data = this->hidden; + unsigned short volatile *p16GP2XRegs = data->io; + + hwdata->uBufSize = width * height * 2; // YUY2 is (2 * width) bytes per line + + // initialize to values that will never be used so that we force a rescale the first time GP2X_DisplayYUVOverlay is called + hwdata->rctLast.h = hwdata->rctLast.w = 0; + hwdata->rctLast.x = hwdata->rctLast.y = -1; + + hwdata->uBackBuf = 0; // arbitrary starting point (can be 0 or 1) + + // We're using GP2X_UPPER_MEM_START because that's where vmem is mapped in SDL_gp2xvideo.c + hwdata->GP2XAddr[0] = GP2X_UPPER_MEM_START; // this is where vmem is mapped from the gp2x's pov + hwdata->GP2XAddr[1] = GP2X_UPPER_MEM_START + hwdata->uBufSize; + + //map memory for our cursor + 4 YUV regions (double buffered each one) + hwdata->YUVBuf[0] = (Uint8 *) data->vmem; + hwdata->YUVBuf[1] = ((Uint8 *) data->vmem) + hwdata->uBufSize; + + // tests have shown that this value should be the width of the overlay, not the width of the display (ie not always 320) + hwdata->u16PixelWidth = width; + + // Set MLC_VLA_TP_PXW + p16GP2XRegs[0x2892>>1] = hwdata->u16PixelWidth; + + // MLC_YUV_CNTL: set YUV source to external memory for regions A and B, turn off "stepping" + p16GP2XRegs[0x2884>>1]=0; + + // disable all RGB Windows, and YUV region B + p16GP2XRegs[MLC_OVLAY_CNTR] &= ~(DISP_STL5EN|DISP_STL4EN|DISP_STL3EN|DISP_STL2EN|DISP_STL1EN|DISP_VLBON); + + // enable YUV region A + p16GP2XRegs[MLC_OVLAY_CNTR] |= DISP_VLAON; + + // disable bottom regions for A & B, and turn off all mirroring + p16GP2XRegs[0x2882>>1] &= 0xFC00; + + // Region B is disabled so we (hopefully) don't need to set anything for it + + // There currently is no way for this function to fail, but I'm leaving this in in case a future way presents itself + iSuccess = 1; + + return iSuccess; +} + +SDL_Overlay *GP2X_CreateYUVOverlay(_THIS, int width, int height, Uint32 format, SDL_Surface *display) +{ + SDL_Overlay *overlay = NULL; + struct private_yuvhwdata *hwdata; + + // we ONLY support YUY2 because that is the native gp2x YUV format + if (format != SDL_YUY2_OVERLAY) + { + printf("SDL_GP2X: Unsupported YUV format for hardware acceleration. Falling back to software.\n"); + return NULL; + } + + /* Create the overlay structure */ + overlay = (SDL_Overlay *)malloc(sizeof *overlay); + if ( overlay == NULL ) { + SDL_OutOfMemory(); + return(NULL); + } + memset(overlay, 0, (sizeof *overlay)); + + /* Fill in the basic members */ + overlay->format = format; + overlay->w = width; + overlay->h = height; + + /* Set up the YUV surface function structure */ + overlay->hwfuncs = &gp2x_yuvfuncs; + + // save our registers + GP2X_SaveRestoreRegs(this, 1); + +#ifdef GP2X_DEBUG + // this is a self-test precaution + { + SDL_PrivateVideoData *data = this->hidden; + unsigned short volatile *p16GP2XRegs = data->io; + g_pRegTester = malloc(0x50); + memcpy(g_pRegTester, (const void *) &p16GP2XRegs[0x2880 >> 1], 0x50); // store a big chunk of register info so we can compare it later + } +#endif // GP2X_DEBUG + + /* Create the pixel data and lookup tables */ + hwdata = (struct private_yuvhwdata *)malloc(sizeof *hwdata); + overlay->hwdata = hwdata; + if ( hwdata == NULL ) + { + SDL_OutOfMemory(); + SDL_FreeYUVOverlay(overlay); + return(NULL); + } + + // if YUV setup failed + if (!GP2X_SetupYUV(this, width, height, format, hwdata)) + { + SDL_FreeYUVOverlay(overlay); + return(NULL); + } + + overlay->hw_overlay = 1; + + /* Set up the plane pointers */ + overlay->pitches = hwdata->pitches; + overlay->pixels = hwdata->planes; + overlay->planes = 1; // since we only support YUY2, there is always only 1 plane + + // the pitch will always be the overlay width * 2, because we only support YUY2 + overlay->pitches[0] = overlay->w * 2; + + // start on the correct back buffer + overlay->pixels[0] = hwdata->YUVBuf[hwdata->uBackBuf]; + + /* We're all done.. */ + printf("SDL_GP2X: Created YUY2 overlay\n"); + return(overlay); +} + +int GP2X_LockYUVOverlay(_THIS, SDL_Overlay *overlay) +{ + return(0); +} + +void GP2X_UnlockYUVOverlay(_THIS, SDL_Overlay *overlay) +{ +} + +int GP2X_DisplayYUVOverlay(_THIS, SDL_Overlay *overlay, SDL_Rect *dstrect) +{ + struct private_yuvhwdata *hwdata = overlay->hwdata; + unsigned int uAddress = (unsigned int) hwdata->GP2XAddr[hwdata->uBackBuf]; + SDL_PrivateVideoData *data = this->hidden; + unsigned short volatile *p16GP2XRegs = data->io; + + // check to see if we are using a different rectangle + // (This should be a faster way than doing a bunch of conditionals and comparisons) + if (((dstrect->w ^ hwdata->rctLast.w) | (dstrect->h ^ hwdata->rctLast.h) | (dstrect->x ^ hwdata->rctLast.x) | + (dstrect->y ^ hwdata->rctLast.y)) == 0) + { + // if we get here, it means that the rectangle size has not changed, so we can flip after vblank + GP2X_WaitVBlank(data); + } + // else we are using a different rectangle + else + { + Uint16 u16HScaleVal = (unsigned short)((1024 * overlay->w) / dstrect->w); + unsigned int uVScaleVal = (unsigned int) ((hwdata->u16PixelWidth * overlay->h) / dstrect->h); + + // the boundary of the window on the right and bottom sides + // (-1 because 0 is the first pixel) + Sint16 s16Right, s16Bottom; + Sint16 x = dstrect->x; + Sint16 y = dstrect->y; + +#ifdef GP2X_DEBUG + // warn the user if this extra math is being done every frame + printf("SDL_GP2X: GP2X YUV Overlay is being resized. This usually should NOT happen every frame!\n"); +#endif // GP2X_DEV + + // gp2x doesn't seem to handle negative coordinates + if (x < 0) x = 0; + if (y < 0) y = 0; + + s16Right = x + (dstrect->w - 1); + s16Bottom = y + (dstrect->h - 1); + + // gp2x doesn't seem like the coordinates going outside the physical boundaries + if (s16Right > 319) s16Right = 319; + if (s16Bottom > 239) s16Bottom = 239; + + // now that we've done all the calculations we can before changing registers, wait for vblank + GP2X_WaitVBlank(data); + + // we need to rescale now ... + // MLC_YUVA_TP_HSC (horizontal scale factor of Region A, top) + p16GP2XRegs[0x2886>>1] = u16HScaleVal; + + // MLC_YUVA_TP_VSC[L/H] (vertical scale factor of Region A, top) + p16GP2XRegs[0x288A>>1] = (unsigned short) (uVScaleVal & 0xFFFF); + p16GP2XRegs[0x288C>>1] = (unsigned short) (uVScaleVal >> 16); // this will usually be 0 + + // NOW SET COORDINATES + + // MLC_YUVA_STX (X start coordinate of region A) + p16GP2XRegs[0x2896>>1]=x; + + // MLC_YUVA_ENDX (X stop coordinate of region A) + p16GP2XRegs[0x2898>>1]=s16Right; + + // MLC_YUV_TP_STY (Y start coordinate of region A top) + p16GP2XRegs[0x289A>>1]=y; + + // MLC_YUV_TP_ENDY (Y stop coordinate of region A top, and the start of the bottom) + p16GP2XRegs[0x289C>>1] = s16Bottom; + + // MLC_YUV_BT_ENDY (Y stop coordinate of region A bottom) + p16GP2XRegs[0x289E>>1] = s16Bottom; + + // copy new rectangle over to rctLast so that we don't do this stuff on every single frame + hwdata->rctLast = *dstrect; + } + + // NOW FLIP THE ACTUAL BUFFER + + // NOTE : I am flipping the odd and even fields here because that's how rlyeh did it, but I am not sure + // whether both of these need to be flipped. + + // region A, odd fields + p16GP2XRegs[0x28A0>>1] = (uAddress & 0xFFFF); + p16GP2XRegs[0x28A2>>1] = (uAddress >> 16); + + // region A, even fields + p16GP2XRegs[0x28A4>>1] = (uAddress & 0xFFFF); + p16GP2XRegs[0x28A6>>1] = (uAddress >> 16); + + // change back buffer to the other buffer (can be 0 or 1, so XOR works nicely) + hwdata->uBackBuf ^= 1; + + // update the pixel pointer to new back buffer + overlay->pixels[0] = hwdata->YUVBuf[hwdata->uBackBuf]; + + return(0); +} + +void GP2X_FreeYUVOverlay(_THIS, SDL_Overlay *overlay) +{ + struct private_yuvhwdata *hwdata; + unsigned short volatile *p16GP2XRegs = this->hidden->io; + + hwdata = overlay->hwdata; + + if ( hwdata ) + { + free(hwdata); + } + + // restore our registers + GP2X_SaveRestoreRegs(this, 0); + +#ifdef GP2X_DEBUG + // this is a self-test precaution + + // make sure that the registers were restored properly + assert (memcmp(g_pRegTester, (const void *) &p16GP2XRegs[0x2880 >> 1], 0x50) == 0); + + free(g_pRegTester); +#endif // GP2X_DEBUG + +} + + Added: trunk/libs-new/sdl/sdl/SDL-1.2.13/src/video/gp2x/SDL_gp2xyuv_c.h =================================================================== --- trunk/libs-new/sdl/sdl/SDL-1.2.13/src/video/gp2x/SDL_gp2xyuv_c.h (rev 0) +++ trunk/libs-new/sdl/sdl/SDL-1.2.13/src/video/gp2x/SDL_gp2xyuv_c.h 2008-08-25 09:47:45 UTC (rev 327) @@ -0,0 +1,34 @@ +/* + SDL - Simple DirectMedia Layer - SDL_gp2xyuv extension + Copyright (C) 2007 Matt Ownby + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +/* This is the GP2X implementation of YUV video overlays */ + +#include "SDL_video.h" +#include "SDL_gp2xvideo.h" + +extern SDL_Overlay *GP2X_CreateYUVOverlay(_THIS, int width, int height, Uint32 format, SDL_Surface *display); + +extern int GP2X_LockYUVOverlay(_THIS, SDL_Overlay *overlay); + +extern void GP2X_UnlockYUVOverlay(_THIS, SDL_Overlay *overlay); + +extern int GP2X_DisplayYUVOverlay(_THIS, SDL_Overlay *overlay, SDL_Rect *dstrect); + +extern void GP2X_FreeYUVOverlay(_THIS, SDL_Overlay *overlay); + Modified: trunk/libs-new/sdl/sdl/SDL-1.2.13/src/video/gp2x/gp2x_tslib.c =================================================================== --- trunk/libs-new/sdl/sdl/SDL-1.2.13/src/video/gp2x/gp2x_tslib.c 2008-08-19 11:43:56 UTC (rev 326) +++ trunk/libs-new/sdl/sdl/SDL-1.2.13/src/video/gp2x/gp2x_tslib.c 2008-08-25 09:47:45 UTC (rev 327) @@ -722,6 +722,206 @@ int y; } XYHIST; +#define XYHISTLENGTH 15 +XYHIST average_xyhist[XYHISTLENGTH]; + +static inline int average_read(TSDEV *ts, TS_SAMPLE *samp, int nr) +{ + + int ret = 0; + int newx, newy; + + int flush_history = 0; // variance module will tell us if we are getting fast movements + static int flush_count = 0; // when we get enough fast movements, flush the history + static int xyhist_full = 0; //DKS - when we have a full four samples, this is 1 + static int xyhist_counter = 0; // DKS - how many entires in history? + static int xyhist_index = 0; //xyhist_index - 1 is index to most-recent sample in array + + ret = variance_read(ts, samp, nr, &flush_history); + flush_count += flush_history; + struct ts_sample *s; + s = samp + (ret - 1); // this module can handle more than one sample, but the gp2x + // touchscreen driver only ever provides 1 sample each read so + // it's not really necessary but not really inefficient either way + int i; + + for( i = ret; i > 0; i--, s--) { + if ((s->pressure == 0) || (flush_count > 7)) { + // when pen is lifted, or a fast movement is detected, flush stored history + xyhist_full = 0; + xyhist_counter = 0; + xyhist_index = 0; + flush_count = 0; + } else { + average_xyhist[xyhist_index].x = s->x; + average_xyhist[xyhist_index].y = s->y; + + xyhist_counter++; + if (xyhist_counter == XYHISTLENGTH) { + xyhist_full = 1; + } + + xyhist_index++; + if (xyhist_index == XYHISTLENGTH) { + xyhist_index = 0; // point back at beginning since array is full + } + + if (xyhist_full) { + //we have a full sample history, we can average this sample with the others + + int j = xyhist_index - 1; // point j to most recent entry in history + if (j < 0) { + j = XYHISTLENGTH - 1; + } + + // 15-sample weighted average, pyramid, provides great smoothing for precise + // operations like menus and drawing + + // sample 1 has weight of * 1 + newx = average_xyhist[j].x; + newy = average_xyhist[j].y; + + j--; + if (j < 0) { + j = XYHISTLENGTH - 1; + } + + // sample 2 has weight of * 2 + newx += average_xyhist[j].x << 1; + newy += average_xyhist[j].y << 1; + + j--; + if (j < 0) { + j = XYHISTLENGTH - 1; + } + + // sample 3 has weight of * 3 + newx += (average_xyhist[j].x << 1) + average_xyhist[j].x; + newy += (average_xyhist[j].y << 1) + average_xyhist[j].y; + + j--; + if (j < 0) { + j = XYHISTLENGTH - 1; + } + + // sample 4 has weight of * 4 + newx += average_xyhist[j].x << 2; + newy += average_xyhist[j].y << 2; + + j--; + if (j < 0) { + j = XYHISTLENGTH - 1; + } + + // sample 5 has weight of * 5 + newx += (average_xyhist[j].x << 2) + average_xyhist[j].x; + newy += (average_xyhist[j].y << 2) + average_xyhist[j].y; + + j--; + if (j < 0) { + j = XYHISTLENGTH - 1; + } + + // sample 6 has weight of * 6 + newx += (average_xyhist[j].x << 2) + (average_xyhist[j].x << 1); + newy += (average_xyhist[j].y << 2) + (average_xyhist[j].y << 1); + + j--; + if (j < 0) { + j = XYHISTLENGTH - 1; + } + + // sample 7 has weight of * 7 + newx += (average_xyhist[j].x << 3) - average_xyhist[j].x; + newy += (average_xyhist[j].y << 3) - average_xyhist[j].y; + + j--; + if (j < 0) { + j = XYHISTLENGTH - 1; + } + + // sample 8, middle sample, has weight of * 8 + newx += (average_xyhist[j].x << 3); + newy += (average_xyhist[j].y << 3); + + j--; + if (j < 0) { + j = XYHISTLENGTH - 1; + } + + // sample 9 has weight of * 7 + newx += (average_xyhist[j].x << 3) - average_xyhist[j].x; + newy += (average_xyhist[j].y << 3) - average_xyhist[j].y; + + j--; + if (j < 0) { + j = XYHISTLENGTH - 1; + } + + // sample 10 has weight of * 6 + newx += (average_xyhist[j].x << 2) + (average_xyhist[j].x << 1); + newy += (average_xyhist[j].y << 2) + (average_xyhist[j].y << 1); + + j--; + if (j < 0) { + j = XYHISTLENGTH - 1; + } + + // sample 11 has weight of * 5 + newx += (average_xyhist[j].x << 2) + average_xyhist[j].x; + newy += (average_xyhist[j].y << 2) + average_xyhist[j].y; + + j--; + if (j < 0) { + j = XYHISTLENGTH - 1; + } + + // sample 12 has weight of * 4 + newx += average_xyhist[j].x << 2; + newy += average_xyhist[j].y << 2; + + j--; + if (j < 0) { + j = XYHISTLENGTH - 1; + } + + // sample 13 has weight of * 3 + newx += (average_xyhist[j].x << 1) + average_xyhist[j].x; + newy += (average_xyhist[j].y << 1) + average_xyhist[j].y; + + j--; + if (j < 0) { + j = XYHISTLENGTH - 1; + } + + // sample 14 has weight of * 2 + newx += average_xyhist[j].x << 1; + newy += average_xyhist[j].y << 1; + + j--; + if (j < 0) { + j = XYHISTLENGTH - 1; + } + + // sample 15 has weight of * 1 + newx += average_xyhist[j].x; + newy += average_xyhist[j].y; + + j--; + if (j < 0) { + j = XYHISTLENGTH - 1; + } + + // divide results by 64 to provide average + samp->x = newx >> 6; + samp->y = newy >> 6; + } + } + } + + return ret; +} +//DKS - non-pyramid form of the above, I cannot tell a real difference, will use pyramid for now. //#define XYHISTLENGTH 15 //XYHIST average_xyhist[XYHISTLENGTH]; // @@ -777,70 +977,69 @@ // // 15-sample weighted average, pyramid, provides great smoothing for precise // // operations like menus and drawing // -// // sample 1 has weight of * 1 -// newx = average_xyhist[j].x; -// newy = average_xyhist[j].y; +// // sample 1 has weight of * 15 +// newx = average_xyhist[j].x * 15; +// newy = average_xyhist[j].y * 15; // // j--; // if (j < 0) { // j = XYHISTLENGTH - 1; // } // -// // sample 2 has weight of * 2 -// newx += average_xyhist[j].x << 1; -// newy += average_xyhist[j].y << 1; +// // sample 2 has weight of * 14 +// newx += average_xyhist[j].x * 14; +// newy += average_xyhist[j].y * 14; // // j--; // if (j < 0) { // j = XYHISTLENGTH - 1; // } // -// // sample 3 has weight of * 3 -// newx += (average_xyhist[j].x << 1) + average_xyhist[j].x; -// newy += (average_xyhist[j].y << 1) + average_xyhist[j].y; -// +// // sample 3 has weight of * 13 +// newx += average_xyhist[j].x * 13; +// newy += average_xyhist[j].y * 13; // j--; // if (j < 0) { // j = XYHISTLENGTH - 1; // } // -// // sample 4 has weight of * 4 -// newx += average_xyhist[j].x << 2; -// newy += average_xyhist[j].y << 2; +// // sample 4 has weight of * 12 +// newx += average_xyhist[j].x * 12; +// newy += average_xyhist[j].y * 12; // // j--; // if (j < 0) { // j = XYHISTLENGTH - 1; // } // -// // sample 5 has weight of * 5 -// newx += (average_xyhist[j].x << 2) + average_xyhist[j].x; -// newy += (average_xyhist[j].y << 2) + average_xyhist[j].y; +// // sample 5 has weight of * 11 +// newx += average_xyhist[j].x * 11; +// newy += average_xyhist[j].y * 11; // // j--; // if (j < 0) { // j = XYHISTLENGTH - 1; // } // -// // sample 6 has weight of * 6 -// newx += (average_xyhist[j].x << 2) + (average_xyhist[j].x << 1); -// newy += (average_xyhist[j].y << 2) + (average_xyhist[j].y << 1); +// // sample 6 has weight of * 10 +// newx += average_xyhist[j].x * 10; +// newy += average_xyhist[j].y * 10; // // j--; // if (j < 0) { // j = XYHISTLENGTH - 1; // } // -// // sample 7 has weight of * 7 -// newx += (average_xyhist[j].x << 3) - average_xyhist[j].x; -// newy += (average_xyhist[j].y << 3) - average_xyhist[j].y; +// // sample 7 has weight of * 9 +// newx += average_xyhist[j].x * 9; +// newy += average_xyhist[j].y * 9; // // j--; // if (j < 0) { // j = XYHISTLENGTH - 1; // } // -// // sample 8, middle sample, has weight of * 8 +// // sample 8, middle sample, has weight of * 8 // newx += (average_xyhist[j].x << 3); // newy += (average_xyhist[j].y << 3); // @@ -912,213 +1111,15 @@ // j = XYHISTLENGTH - 1; // } // -// // divide results by 64 to provide average -// samp->x = newx >> 6; -// samp->y = newy >> 6; +// samp->x = newx / 120; +// samp->y = newy / 120; // } // } // } // // return ret; //} -#define XYHISTLENGTH 5 -XYHIST average_xyhist[XYHISTLENGTH]; -static inline int average_read(TSDEV *ts, TS_SAMPLE *samp, int nr) -{ - - int ret = 0; - int newx, newy; - - int flush_history = 0; // variance module will tell us if we are getting fast movements - static int flush_count = 0; // when we get enough fast movements, flush the history - static int xyhist_full = 0; //DKS - when we have a full four samples, this is 1 - static int xyhist_counter = 0; // DKS - how many entires in history? - static int xyhist_index = 0; //xyhist_index - 1 is index to most-recent sample in array - - ret = variance_read(ts, samp, nr, &flush_history); - flush_count += flush_history; - struct ts_sample *s; - s = samp + (ret - 1); // this module can handle more than one sample, but the gp2x - // touchscreen driver only ever provides 1 sample each read so - // it's not really necessary but not really inefficient either way - int i; - - for( i = ret; i > 0; i--, s--) { - if ((s->pressure == 0) || (flush_count > 7)) { - // when pen is lifted, or a fast movement is detected, flush stored history - xyhist_full = 0; - xyhist_counter = 0; - xyhist_index = 0; - flush_count = 0; - } else { - average_xyhist[xyhist_index].x = s->x; - average_xyhist[xyhist_index].y = s->y; - - xyhist_counter++; - if (xyhist_counter == XYHISTLENGTH) { - xyhist_full = 1; - } - - xyhist_index++; - if (xyhist_index == XYHISTLENGTH) { - xyhist_index = 0; // point back at beginning since array is full - } - - if (xyhist_full) { - //we have a full sample history, we can average this sample with the others - - int j = xyhist_index - 1; // point j to most recent entry in history - if (j < 0) { - j = XYHISTLENGTH - 1; - } - - // 15-sample weighted average, pyramid, provides great smoothing for precise - // operations like menus and drawing - - // sample 1 has weight of * 15 - newx = average_xyhist[j].x * 15; - newy = average_xyhist[j].y * 15; - - j--; - if (j < 0) { - j = XYHISTLENGTH - 1; - } - - // sample 2 has weight of * 14 - newx += average_xyhist[j].x * 14; - newy += average_xyhist[j].y * 14; - - j--; - if (j < 0) { - j = XYHISTLENGTH - 1; - } - - // sample 3 has weight of * 13 - newx += average_xyhist[j].x * 13; - newy += average_xyhist[j].y * 13; - j--; - if (j < 0) { - j = XYHISTLENGTH - 1; - } - - // sample 4 has weight of * 12 - newx += average_xyhist[j].x * 12; - newy += average_xyhist[j].y * 12; - - j--; - if (j < 0) { - j = XYHISTLENGTH - 1; - } - - // sample 5 has weight of * 11 - newx += average_xyhist[j].x * 11; - newy += average_xyhist[j].y * 11; - - j--; - if (j < 0) { - j = XYHISTLENGTH - 1; - } - - // sample 6 has weight of * 10 - newx += average_xyhist[j].x * 10; - newy += average_xyhist[j].y * 10; - - j--; - if (j < 0) { - j = XYHISTLENGTH - 1; - } - - // sample 7 has weight of * 9 - newx += average_xyhist[j].x * 9; - newy += average_xyhist[j].y * 9; - - j--; - if (j < 0) { - j = XYHISTLENGTH - 1; - } - - // sample 8, middle sample, has weight of * 8 - newx += (average_xyhist[j].x << 3); - newy += (average_xyhist[j].y << 3); - - j--; - if (j < 0) { - j = XYHISTLENGTH - 1; - } - - // sample 9 has weight of * 7 - newx += (average_xyhist[j].x << 3) - average_xyhist[j].x; - newy += (average_xyhist[j].y << 3) - average_xyhist[j].y; - - j--; - if (j < 0) { - j = XYHISTLENGTH - 1; - } - - // sample 10 has weight of * 6 - newx += (average_xyhist[j].x << 2) + (average_xyhist[j].x << 1); - newy += (average_xyhist[j].y << 2) + (average_xyhist[j].y << 1); - - j--; - if (j < 0) { - j = XYHISTLENGTH - 1; - } - - // sample 11 has weight of * 5 - newx += (average_xyhist[j].x << 2) + average_xyhist[j].x; - newy += (average_xyhist[j].y << 2) + average_xyhist[j].y; - - j--; - if (j < 0) { - j = XYHISTLENGTH - 1; - } - - // sample 12 has weight of * 4 - newx += average_xyhist[j].x << 2; - newy += average_xyhist[j].y << 2; - - j--; - if (j < 0) { - j = XYHISTLENGTH - 1; - } - - // sample 13 has weight of * 3 - newx += (average_xyhist[j].x << 1) + average_xyhist[j].x; - newy += (average_xyhist[j].y << 1) + average_xyhist[j].y; - - j--; - if (j < 0) { - j = XYHISTLENGTH - 1; - } - - // sample 14 has weight of * 2 - newx += average_xyhist[j].x << 1; - newy += average_xyhist[j].y << 1; - - j--; - if (j < 0) { - j = XYHISTLENGTH - 1; - } - - // sample 15 has weight of * 1 - newx += average_xyhist[j].x; - newy += average_xyhist[j].y; - - j--; - if (j < 0) { - j = XYHISTLENGTH - 1; - } - - samp->x = newx / 120; - samp->y = newy / 120; - } - } - } - - return ret; -} - /****************************** * linear ******************************/ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |