aboutsummaryrefslogtreecommitdiff
path: root/backends
diff options
context:
space:
mode:
authorOystein Eftevaag2006-02-14 02:19:53 +0000
committerOystein Eftevaag2006-02-14 02:19:53 +0000
commitbef27ff14f1e1e20e01bd4f720bf536af1f1f989 (patch)
tree0c497b39242ad31a075f8c8800c337e6368062ef /backends
parente0b7feeaedbb9393025fef12e0d5390845c0890c (diff)
downloadscummvm-rg350-bef27ff14f1e1e20e01bd4f720bf536af1f1f989.tar.gz
scummvm-rg350-bef27ff14f1e1e20e01bd4f720bf536af1f1f989.tar.bz2
scummvm-rg350-bef27ff14f1e1e20e01bd4f720bf536af1f1f989.zip
Fixed and cleaned up the X11 backend (and added 24/32 bpp support so it would actually run on my system).
Who knows, might actually be useful to someone :) svn-id: r20681
Diffstat (limited to 'backends')
-rw-r--r--backends/x11/x11.cpp784
1 files changed, 360 insertions, 424 deletions
diff --git a/backends/x11/x11.cpp b/backends/x11/x11.cpp
index 7ca303af9a..4b39e707bb 100644
--- a/backends/x11/x11.cpp
+++ b/backends/x11/x11.cpp
@@ -56,195 +56,156 @@
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ioctl.h>
+#include <backends/x11/x11.h>
-class OSystem_X11:public OSystem {
-public:
- // Determine whether the backend supports the specified feature.
- bool hasFeature(Feature f);
-
- // En-/disable the specified feature.
- void setFeatureState(Feature f, bool enable);
-
- // Query the state of the specified feature.
- bool getFeatureState(Feature f);
-
- // Retrieve a list of all graphics modes supported by this backend.
- const GraphicsMode *getSupportedGraphicsModes() const;
-
- // Return the ID of the 'default' graphics mode.
- int getDefaultGraphicsMode() const;
-
- // Switch to the specified graphics mode.
- bool setGraphicsMode(int mode);
-
- // Determine which graphics mode is currently active.
- int getGraphicsMode() const;
-
- // Set colors of the palette
- void setPalette(const byte *colors, uint start, uint num);
-
- // Set the size of the video bitmap.
- // Typically, 320x200
- void initSize(uint w, uint h, int overlaySize);
-
- // Draw a bitmap to screen.
- // The screen will not be updated to reflect the new bitmap
- void copyRectToScreen(const byte *buf, int pitch, int x, int y, int w, int h);
-
- // Update the dirty areas of the screen
- void updateScreen();
-
- // Either show or hide the mouse cursor
- bool showMouse(bool visible);
+OSystem *OSystem_X11_create() {
+ return OSystem_X11::create(0, 0);
+}
- // Set the position of the mouse cursor
- void set_mouse_pos(int x, int y);
+OSystem *OSystem_X11::create(int gfx_mode, bool full_screen) {
+ OSystem_X11 *syst = new OSystem_X11();
+ return syst;
+}
- // Warp the mouse cursor. Where set_mouse_pos() only informs the
- // backend of the mouse cursor's current position, this function
- // actually moves the cursor to the specified position.
- void warpMouse(int x, int y);
+OSystem_X11::OSystem_X11() {
+ /* Some members initialization */
+ _fake_right_mouse = 0;
+ _report_presses = 1;
+ _current_shake_pos = 0;
+ _new_shake_pos = 0;
+ _palette_changed = false;
+ _num_of_dirty_rects = 0;
+ _overlay_visible = false;
+ _mouse_state_changed = true;
+ _mouse_visible = true;
+ _ms_buf = NULL;
+ _curMouseState.x = 0;
+ _curMouseState.y = 0;
+ _curMouseState.hot_x = 0;
+ _curMouseState.hot_y = 0;
+ _curMouseState.w = 0;
+ _curMouseState.h = 0;
+ _palette16 = 0;
+ _palette32 = 0;
+ _bytesPerPixel = 0;
+ _image = 0;
+ _local_fb = 0;
+ _local_fb_overlay = 0;
+}
- // Set the bitmap that's used when drawing the cursor.
- void setMouseCursor(const byte *buf, uint w, uint h, int hotspot_x, int hotspot_y, byte keycolor);
+OSystem_X11::~OSystem_X11() {
+ XFree(_image);
+ if (_palette16)
+ free(_palette16);
- // Shaking is used in SCUMM. Set current shake position.
- void setShakePos(int shake_pos);
+ if (_palette32)
+ free(_palette32);
- // Get the number of milliseconds since the program was started.
- uint32 getMillis();
+ if (_ms_buf)
+ free(_ms_buf);
- // Delay for a specified amount of milliseconds
- void delayMillis(uint msecs);
+ free(_local_fb_overlay);
+ free(_local_fb);
+}
- // Get the next event.
- // Returns true if an event was retrieved.
- bool pollEvent(Event &event);
+void OSystem_X11::initBackend() {
+ char buf[512];
+ XWMHints *wm_hints;
+ XGCValues values;
+ XTextProperty window_name;
+ char *name = (char *)&buf;
+ /* For the_window title */
+ sprintf(buf, "ScummVM");
- // Set function that generates samples
- bool setSoundCallback(SoundProc proc, void *param);
- void clearSoundCallback();
+ _display = XOpenDisplay(NULL);
+ if (_display == NULL) {
+ error("Could not open display !\n");
+ exit(1);
+ }
- // Determine the output sample rate. Audio data provided by the sound
- // callback will be played using this rate.
- int getOutputSampleRate() const;
+ if (XShmQueryExtension(_display)!=True)
+ error("No Shared Memory Extension present");
- // Initialise the specified CD drive for audio playback.
- bool openCD(int drive);
+ _screen = DefaultScreen(_display);
+ _depth = DefaultDepth(_display, _screen);
+ switch (_depth) {
+ case 16 :
+ _bytesPerPixel = 2;
+ break;
+ case 24 :
+ case 32 :
+ _bytesPerPixel = 4;
+ break;
+ }
- // Poll cdrom status
- // Returns true if cd audio is playing
- bool pollCD();
+ if (!_bytesPerPixel)
+ error("Your screen depth is %ibit. Values other than 16, 24 and 32bit are currently not supported", _depth);
- // Play cdrom audio track
- void playCD(int track, int num_loops, int start_frame, int duration);
+ _window_width = 320;
+ _window_height = 200;
+ _scumm_x = 0;
+ _scumm_y = 0;
+ _window = XCreateSimpleWindow(_display, XRootWindow(_display, _screen), 0, 0, 320, 200, 0, 0, 0);
+ wm_hints = XAllocWMHints();
+ if (wm_hints == NULL) {
+ error("Not enough memory to allocate Hints !\n");
+ exit(1);
+ }
+ wm_hints->flags = InputHint | StateHint;
+ wm_hints->input = True;
+ wm_hints->initial_state = NormalState;
+ XStringListToTextProperty(&name, 1, &window_name);
+ XSetWMProperties(_display, _window, &window_name, &window_name,
+ NULL /* argv */ , 0 /* argc */ , NULL /* size hints */ ,
+ wm_hints, NULL /* class hints */ );
+ XFree(wm_hints);
- // Stop cdrom audio track
- void stopCD();
+ XSelectInput(_display, _window,
+ ExposureMask | KeyPressMask | KeyReleaseMask |
+ PointerMotionMask | ButtonPressMask | ButtonReleaseMask | StructureNotifyMask);
- // Update cdrom audio status
- void updateCD();
+ values.foreground = BlackPixel(_display, _screen);
+ _black_gc = XCreateGC(_display, _window, GCForeground, &values);
- // Quit
- void quit();
+ XMapWindow(_display, _window);
+ XFlush(_display);
- // Add a callback timer
- void setTimerCallback(TimerProc callback, int interval);
+ _fb_width = 0;
+ _fb_height = 0;
- // Mutex handling
- MutexRef createMutex();
- void lockMutex(MutexRef mutex);
- void unlockMutex(MutexRef mutex);
- void deleteMutex(MutexRef mutex);
+ if (!_palette16)
+ _palette16 = (uint16 *)calloc(256, sizeof(uint16));
+ if (!_palette32 && _bytesPerPixel == 4)
+ _palette32 = (uint32 *)calloc(256, sizeof(uint32));
- // Overlay handling for the new menu system
- void showOverlay();
- void hideOverlay();
- void clearOverlay();
- void grabOverlay(int16 *, int);
- void copyRectToOverlay(const int16 *, int, int, int, int, int);
- virtual int16 getHeight();
- virtual int16 getWidth();
+ while (1) {
+ XEvent event;
+ XNextEvent(_display, &event);
+ switch (event.type) {
+ case Expose:
+ goto out_of_loop;
+ }
+ }
+out_of_loop:
+ create_empty_cursor();
- // Set a window caption or any other comparable status display to the
- // given value.
- void setWindowCaption(const char *caption);
+ /* Initialize the timer routines */
+ _timer_active = false;
+ /* And finally start the local timer */
+ gettimeofday(&_start_time, NULL);
- static OSystem *create(int gfx_mode, bool full_screen);
-
-private:
- OSystem_X11();
-
- typedef struct {
- int x, y, w, h;
- } dirty_square;
-
- void create_empty_cursor();
- void draw_mouse(dirty_square *dout);
- void undraw_mouse();
- void updateScreen_helper(const dirty_square * d, dirty_square * dout);
- void blit_convert(const dirty_square * d, uint16 *dst, int pitch);
-
- uint8 *local_fb;
- uint16 *local_fb_overlay;
- bool _overlay_visible;
-
- int window_width, window_height;
- int fb_width, fb_height;
- int scumm_x, scumm_y;
-
- uint16 *palette;
- bool _palette_changed;
- Display *display;
- int screen, depth;
- Window window;
- GC black_gc;
- XImage *image;
- pthread_t sound_thread;
-
- int fake_right_mouse;
- int report_presses;
- int current_shake_pos;
- int new_shake_pos;
- struct timeval start_time;
-
- enum {
- MAX_NUMBER_OF_DIRTY_SQUARES = 32
- };
- dirty_square ds[MAX_NUMBER_OF_DIRTY_SQUARES];
- int num_of_dirty_square;
-
- typedef struct {
- int x, y;
- int w, h;
- int hot_x, hot_y;
- } mouse_state;
- mouse_state old_state, cur_state;
- byte *_ms_buf;
- bool _mouse_visible;
- bool _mouse_state_changed;
- byte _mouseKeycolor;
-
- uint32 _timer_duration, _timer_next_expiry;
- bool _timer_active;
- int (*_timer_callback) (int);
-};
-
-typedef struct {
- OSystem::SoundProc sound_proc;
- void *param;
-} THREAD_PARAM;
+}
#undef CAPTURE_SOUND
-
#define FRAG_SIZE 4096
+
static void *sound_and_music_thread(void *params) {
/* Init sound */
int sound_fd, param, frag_size;
uint8 sound_buffer[FRAG_SIZE];
- OSystem::SoundProc sound_proc = ((THREAD_PARAM *) params)->sound_proc;
- void *proc_param = ((THREAD_PARAM *) params)->param;
+ OSystem::SoundProc sound_proc = ((THREAD_PARAM *)params)->sound_proc;
+ void *proc_param = ((THREAD_PARAM *)params)->param;
#ifdef CAPTURE_SOUND
FILE *f = fopen("sound.raw", "wb");
@@ -253,8 +214,8 @@ static void *sound_and_music_thread(void *params) {
sound_fd = open("/dev/dsp", O_WRONLY);
audio_buf_info info;
if (sound_fd < 0) {
- error("Error opening sound device !\n");
- exit(1);
+ warning("Error opening sound device!\n");
+ return NULL;
}
param = 0;
frag_size = FRAG_SIZE /* audio fragment size */ ;
@@ -265,39 +226,39 @@ static void *sound_and_music_thread(void *params) {
param--;
param |= /* audio_fragment_num */ 3 << 16;
if (ioctl(sound_fd, SNDCTL_DSP_SETFRAGMENT, &param) != 0) {
- error("Error in the SNDCTL_DSP_SETFRAGMENT ioctl !\n");
- exit(1);
+ warning("Error in the SNDCTL_DSP_SETFRAGMENT ioctl!\n");
+ return NULL;
}
param = AFMT_S16_LE;
if (ioctl(sound_fd, SNDCTL_DSP_SETFMT, &param) == -1) {
- perror("Error in the SNDCTL_DSP_SETFMT ioctl !\n");
- exit(1);
+ warning("Error in the SNDCTL_DSP_SETFMT ioctl!\n");
+ return NULL;;
}
if (param != AFMT_S16_LE) {
- error("AFMT_S16_LE not supported !\n");
- exit(1);
+ warning("AFMT_S16_LE not supported!\n");
+ return NULL;
}
param = 2;
if (ioctl(sound_fd, SNDCTL_DSP_CHANNELS, &param) == -1) {
- error("Error in the SNDCTL_DSP_CHANNELS ioctl !\n");
- exit(1);
+ warning("Error in the SNDCTL_DSP_CHANNELS ioctl!\n");
+ return NULL;
}
if (param != 2) {
- error("Stereo mode not supported !\n");
- exit(1);
+ warning("Stereo mode not supported!\n");
+ return NULL;
}
param = SAMPLES_PER_SEC;
if (ioctl(sound_fd, SNDCTL_DSP_SPEED, &param) == -1) {
- perror("Error in the SNDCTL_DSP_SPEED ioctl !\n");
- exit(1);
+ warning("Error in the SNDCTL_DSP_SPEED ioctl!\n");
+ return NULL;
}
if (param != SAMPLES_PER_SEC) {
- error("%d kHz not supported !\n", SAMPLES_PER_SEC);
- exit(1);
+ warning("%d kHz not supported!\n", SAMPLES_PER_SEC);
+ return NULL;
}
if (ioctl(sound_fd, SNDCTL_DSP_GETOSPACE, &info) != 0) {
- perror("SNDCTL_DSP_GETOSPACE");
- exit(-1);
+ warning("SNDCTL_DSP_GETOSPACE");
+ return NULL;
}
sched_yield();
@@ -329,110 +290,12 @@ void OSystem_X11::create_empty_cursor() {
static const char data[] = { 0 };
bg.red = bg.green = bg.blue = 0x0000;
- pixmapBits = XCreateBitmapFromData(display, XRootWindow(display, screen), data, 1, 1);
+ pixmapBits = XCreateBitmapFromData(_display, XRootWindow(_display, _screen), data, 1, 1);
if (pixmapBits) {
- cursor = XCreatePixmapCursor(display, pixmapBits, pixmapBits, &bg, &bg, 0, 0);
- XFreePixmap(display, pixmapBits);
- }
- XDefineCursor(display, window, cursor);
-}
-
-OSystem *OSystem_X11_create() {
- return OSystem_X11::create(0, 0);
-}
-
-OSystem *OSystem_X11::create(int gfx_mode, bool full_screen) {
- OSystem_X11 *syst = new OSystem_X11();
- return syst;
-}
-
-OSystem_X11::OSystem_X11() {
- char buf[512];
- XWMHints *wm_hints;
- XGCValues values;
- XTextProperty window_name;
- char *name = (char *)&buf;
-
- /* Some members initialization */
- fake_right_mouse = 0;
- report_presses = 1;
- current_shake_pos = 0;
- new_shake_pos = 0;
- _palette_changed = false;
- num_of_dirty_square = 0;
- _overlay_visible = false;
- _mouse_state_changed = true;
- _mouse_visible = true;
- _ms_buf = NULL;
- cur_state.x = 0;
- cur_state.y = 0;
- cur_state.hot_x = 0;
- cur_state.hot_y = 0;
- cur_state.w = 0;
- cur_state.h = 0;
-
- /* For the window title */
- sprintf(buf, "ScummVM");
-
- display = XOpenDisplay(NULL);
- if (display == NULL) {
- error("Could not open display !\n");
- exit(1);
- }
-
- if (XShmQueryExtension(display)!=True)
- error("No Shared Memory Extension present");
-
- screen = DefaultScreen(display);
- depth = DefaultDepth(display,screen);
- if (depth != 16)
- error("Your screen depth is %ibit. Values other than 16bit are currently not supported", depth);
-
- window_width = 320;
- window_height = 200;
- scumm_x = 0;
- scumm_y = 0;
- window = XCreateSimpleWindow(display, XRootWindow(display, screen), 0, 0, 320, 200, 0, 0, 0);
- wm_hints = XAllocWMHints();
- if (wm_hints == NULL) {
- error("Not enough memory to allocate Hints !\n");
- exit(1);
- }
- wm_hints->flags = InputHint | StateHint;
- wm_hints->input = True;
- wm_hints->initial_state = NormalState;
- XStringListToTextProperty(&name, 1, &window_name);
- XSetWMProperties(display, window, &window_name, &window_name,
- NULL /* argv */ , 0 /* argc */ , NULL /* size hints */ ,
- wm_hints, NULL /* class hints */ );
- XFree(wm_hints);
-
- XSelectInput(display, window,
- ExposureMask | KeyPressMask | KeyReleaseMask |
- PointerMotionMask | ButtonPressMask | ButtonReleaseMask | StructureNotifyMask);
-
- values.foreground = BlackPixel(display, screen);
- black_gc = XCreateGC(display, window, GCForeground, &values);
-
- XMapWindow(display, window);
- XFlush(display);
-
- while (1) {
- XEvent event;
- XNextEvent(display, &event);
- switch (event.type) {
- case Expose:
- goto out_of_loop;
- }
+ cursor = XCreatePixmapCursor(_display, pixmapBits, pixmapBits, &bg, &bg, 0, 0);
+ XFreePixmap(_display, pixmapBits);
}
-out_of_loop:
- create_empty_cursor();
-
- /* Initialize the timer routines */
- _timer_active = false;
-
- /* And finally start the local timer */
- gettimeofday(&start_time, NULL);
+ XDefineCursor(_display, _window, cursor);
}
bool OSystem_X11::hasFeature(Feature f) {
@@ -447,7 +310,8 @@ bool OSystem_X11::getFeatureState(Feature f) {
}
const OSystem::GraphicsMode *OSystem_X11::getSupportedGraphicsModes() const {
- return NULL; // TODO / FIXME
+ static const OSystem::GraphicsMode mode = {"1x", "Normal mode", 0};
+ return &mode;
}
int OSystem_X11::getDefaultGraphicsMode() const {
@@ -466,46 +330,53 @@ int OSystem_X11::getGraphicsMode() const {
uint32 OSystem_X11::getMillis() {
struct timeval current_time;
gettimeofday(&current_time, NULL);
- return (uint32)(((current_time.tv_sec - start_time.tv_sec) * 1000) +
- ((current_time.tv_usec - start_time.tv_usec) / 1000));
+ return (uint32)(((current_time.tv_sec - _start_time.tv_sec) * 1000) +
+ ((current_time.tv_usec - _start_time.tv_usec) / 1000));
}
void OSystem_X11::initSize(uint w, uint h, int overlaySize) {
+ //debug("initSize(%i, %i, %i)", w, h, overlaySize);
static XShmSegmentInfo shminfo;
- fb_width = w;
- fb_height = h;
+ if (((uint)_fb_width != w) || ((uint)_fb_height != w)) {
+ _fb_width = w;
+ _fb_height = h;
- if ((fb_width != 320) || (fb_height != 200)) {
- /* We need to change the size of the X11 window */
+ /* We need to change the size of the X11_window */
XWindowChanges new_values;
- new_values.width = fb_width;
- new_values.height = fb_height;
+ new_values.width = _fb_width;
+ new_values.height = _fb_height;
- XConfigureWindow(display, window, CWWidth | CWHeight, &new_values);
- }
+ XConfigureWindow(_display,_window, CWWidth | CWHeight, &new_values);
- image = XShmCreateImage(display, DefaultVisual(display, screen), depth, ZPixmap, NULL, &shminfo, fb_width, fb_height);
- if (!image)
- error("Couldn't get image by XShmCreateImage()");
+ if (_image)
+ XFree(_image);
+ _image = XShmCreateImage(_display, DefaultVisual(_display, _screen), _depth, ZPixmap, NULL, &shminfo,_fb_width,_fb_height);
+ if (!_image)
+ error("Couldn't get image by XShmCreateImage()");
- shminfo.shmid = shmget(IPC_PRIVATE, image->bytes_per_line * image->height, IPC_CREAT | 0700);
- if (shminfo.shmid < 0)
- error("Couldn't allocate image data by shmget()");
+ shminfo.shmid = shmget(IPC_PRIVATE, _image->bytes_per_line * _image->height, IPC_CREAT | 0700);
+ if (shminfo.shmid < 0)
+ error("Couldn't allocate image data by shmget()");
- image->data = shminfo.shmaddr = (char *)shmat(shminfo.shmid, 0, 0);
- shminfo.readOnly = False;
- if (XShmAttach(display, &shminfo) == 0) {
- error("Could not attach shared memory segment !\n");
- exit(1);
- }
- shmctl(shminfo.shmid, IPC_RMID, 0);
+ _image->data = shminfo.shmaddr = (char *)shmat(shminfo.shmid, 0, 0);
+ shminfo.readOnly = False;
+ if (XShmAttach(_display, &shminfo) == 0) {
+ error("Could not attach shared memory segment !\n");
+ exit(1);
+ }
+ shmctl(shminfo.shmid, IPC_RMID, 0);
+
+ if (_local_fb)
+ free(_local_fb);
+ if (_local_fb_overlay)
+ free(_local_fb_overlay);
+ /* Initialize the 'local' frame buffer and the palette */
+ _local_fb = (uint8 *)calloc(_fb_width * _fb_height, sizeof(uint8));
+ _local_fb_overlay = (uint16 *)calloc(_fb_width * _fb_height, sizeof(uint16));
- /* Initialize the 'local' frame buffer and the palette */
- local_fb = (uint8 *)calloc(fb_width * fb_height, sizeof(uint8));
- local_fb_overlay = (uint16 *)calloc(fb_width * fb_height, sizeof(uint16));
- palette = (uint16 *)calloc(256, sizeof(uint16));
+ }
}
bool OSystem_X11::setSoundCallback(SoundProc proc, void *param) {
@@ -515,7 +386,7 @@ bool OSystem_X11::setSoundCallback(SoundProc proc, void *param) {
thread_param.param = param;
thread_param.sound_proc = proc;
- pthread_create(&sound_thread, NULL, sound_and_music_thread, (void *)&thread_param);
+ pthread_create(&_sound_thread, NULL, sound_and_music_thread, (void *)&thread_param);
return true;
}
@@ -530,8 +401,15 @@ void OSystem_X11::clearSoundCallback() {
void OSystem_X11::setPalette(const byte *colors, uint start, uint num) {
+ uint16 *pal = &(_palette16[start]);
const byte *data = colors;
- uint16 *pal = &(palette[start]);
+
+ if (_bytesPerPixel == 4) {
+ for (uint i = start; i < start+num; i++) {
+ //_palette32[i] = ((uint32 *)colors)[i];
+ _palette32[i] = (colors[i * 4 + 0] << 16) | (colors[i * 4 + 1] << 8) | (colors[i * 4 + 2] << 0);
+ }
+ }
do {
*pal++ = ((data[0] & 0xF8) << 8) | ((data[1] & 0xFC) << 3) | (data[2] >> 3);
@@ -543,12 +421,12 @@ void OSystem_X11::setPalette(const byte *colors, uint start, uint num) {
}
#define AddDirtyRec(xi,yi,wi,hi) \
- if (num_of_dirty_square < MAX_NUMBER_OF_DIRTY_SQUARES) { \
- ds[num_of_dirty_square].x = xi; \
- ds[num_of_dirty_square].y = yi; \
- ds[num_of_dirty_square].w = wi; \
- ds[num_of_dirty_square].h = hi; \
- num_of_dirty_square++; \
+ if (_num_of_dirty_rects < MAX_NUMBER_OF_DIRTY_RECTS) { \
+ _ds[_num_of_dirty_rects].x = xi; \
+ _ds[_num_of_dirty_rects].y = yi; \
+ _ds[_num_of_dirty_rects].w = wi; \
+ _ds[_num_of_dirty_rects].h = hi; \
+ _num_of_dirty_rects++; \
}
void OSystem_X11::copyRectToScreen(const byte *buf, int pitch, int x, int y, int w, int h) {
@@ -559,11 +437,11 @@ void OSystem_X11::copyRectToScreen(const byte *buf, int pitch, int x, int y, int
buf -= y * pitch;
y = 0;
}
- if (h > (fb_height - y)) {
- h = fb_height - y;
+ if (h > (_fb_height - y)) {
+ h = _fb_height - y;
}
- dst = local_fb + fb_width * y + x;
+ dst = _local_fb + _fb_width * y + x;
if (h <= 0)
return;
@@ -571,37 +449,86 @@ void OSystem_X11::copyRectToScreen(const byte *buf, int pitch, int x, int y, int
AddDirtyRec(x, y, w, h);
while (h-- > 0) {
memcpy(dst, buf, w);
- dst += fb_width;
+ dst +=_fb_width;
buf += pitch;
}
}
-void OSystem_X11::blit_convert(const dirty_square * d, uint16 *dst, int pitch) {
- uint8 *ptr_src = local_fb + (fb_width * d->y) + d->x;
- uint16 *ptr_dst = dst + (fb_width * d->y) + d->x;
+void OSystem_X11::blit(const DirtyRect *d, uint16 *dst, int pitch) {
+ uint8 *ptr_src = _local_fb + (_fb_width * d->y) + d->x;
+ uint16 *ptr_dst = dst + ((_fb_width * d->y) + d->x);
int x, y;
for (y = 0; y < d->h; y++) {
for (x = 0; x < d->w; x++) {
- *ptr_dst++ = palette[*ptr_src++];
+ *ptr_dst++ = _palette16[*ptr_src++];
}
ptr_dst += pitch - d->w;
- ptr_src += fb_width - d->w;
+ ptr_src +=_fb_width - d->w;
}
}
-void OSystem_X11::updateScreen_helper(const dirty_square * d, dirty_square * dout) {
+void OSystem_X11::blit_convert(const DirtyRect *d, uint8 *dst, int pitch) {
+ uint8 *ptr_src = _local_fb + (_fb_width * d->y) + d->x;
+ uint8 *ptr_dst = dst + ((_fb_width * d->y) + d->x) * _bytesPerPixel;
+ int x, y;
+
+ switch (_bytesPerPixel) {
+ case 2:
+ for (y = 0; y < d->h; y++) {
+ for (x = 0; x < d->w; x++) {
+ *ptr_dst = _palette16[*ptr_src++];
+ ptr_dst += _bytesPerPixel;
+ }
+ ptr_dst += (pitch - d->w) * _bytesPerPixel;
+ ptr_src +=_fb_width - d->w;
+ }
+ break;
+ case 4:
+ for (y = 0; y < d->h; y++) {
+ for (x = 0; x < d->w; x++) {
+ *(uint32 *)ptr_dst = _palette32[*ptr_src];
+ ptr_dst += _bytesPerPixel;
+ ptr_src++;
+ }
+ ptr_dst += (pitch - d->w) * _bytesPerPixel;
+ ptr_src += _fb_width - d->w;
+ }
+ }
+}
+
+void OSystem_X11::updateScreen_helper(const DirtyRect *d, DirtyRect *dout) {
+
if (_overlay_visible == false) {
- blit_convert(d, (uint16 *) image->data, fb_width);
+ blit_convert(d, (uint8 *)_image->data, _fb_width);
} else {
- uint16 *ptr_src = local_fb_overlay + (fb_width * d->y) + d->x;
- uint16 *ptr_dst = ((uint16 *)image->data) + (fb_width * d->y) + d->x;
+ uint16 *ptr_src = _local_fb_overlay + (_fb_width * d->y) + d->x;
+ uint8 *ptr_dst = (uint8 *)_image->data + ((_fb_width * d->y) + d->x) * _bytesPerPixel;
+
int y;
- for (y = 0; y < d->h; y++) {
- memcpy(ptr_dst, ptr_src, d->w * sizeof(uint16));
- ptr_dst += fb_width;
- ptr_src += fb_width;
+ switch (_bytesPerPixel) {
+ case 2:
+ for (y = 0; y < d->h; y++) {
+ memcpy(ptr_dst, ptr_src, d->w * sizeof(uint16));
+ ptr_dst += _fb_width * sizeof(uint16);
+ ptr_src += _fb_width;
+ }
+ break;
+ case 4:
+ uint16 currLine, x;
+ register uint16 currPixel;
+ for (y = d->y; y < d->y + d->h; y++) {
+ currLine = y * _fb_width;
+ for (x = d->x; x < d->x + d->w; x++) {
+ currPixel = _local_fb_overlay[(currLine + x)];
+ *(uint32 *)ptr_dst = ((currPixel & 0xF800) << 8) + ((currPixel & 0x07E0) << 5) +
+ ((currPixel & 0x001F) << 3);
+ ptr_dst += sizeof(uint32);
+ }
+ ptr_dst += (_fb_width - d->w) * _bytesPerPixel;
+ }
+
}
}
if (d->x < dout->x)
@@ -617,47 +544,47 @@ void OSystem_X11::updateScreen_helper(const dirty_square * d, dirty_square * dou
void OSystem_X11::updateScreen() {
bool full_redraw = false;
bool need_redraw = false;
- static const dirty_square ds_full = { 0, 0, fb_width, fb_height };
- dirty_square dout = { fb_width, fb_height, 0, 0 };
+ static const DirtyRect ds_full = { 0, 0, _fb_width, _fb_height };
+ DirtyRect dout = {_fb_width, _fb_height, 0, 0 };
if (_palette_changed) {
full_redraw = true;
- num_of_dirty_square = 0;
+ _num_of_dirty_rects = 0;
_palette_changed = false;
- } else if (num_of_dirty_square >= MAX_NUMBER_OF_DIRTY_SQUARES) {
+ } else if (_num_of_dirty_rects >= MAX_NUMBER_OF_DIRTY_RECTS) {
full_redraw = true;
- num_of_dirty_square = 0;
+ _num_of_dirty_rects = 0;
}
if (full_redraw) {
updateScreen_helper(&ds_full, &dout);
need_redraw = true;
- } else if ((num_of_dirty_square > 0) || (_mouse_state_changed == true)) {
+ } else if ((_num_of_dirty_rects > 0) || (_mouse_state_changed == true)) {
need_redraw = true;
- while (num_of_dirty_square > 0) {
- num_of_dirty_square--;
- updateScreen_helper(&(ds[num_of_dirty_square]), &dout);
+ while (_num_of_dirty_rects > 0) {
+ _num_of_dirty_rects--;
+ updateScreen_helper(&(_ds[_num_of_dirty_rects]), &dout);
}
}
/* Then 'overlay' the mouse on the image */
draw_mouse(&dout);
- if (current_shake_pos != new_shake_pos) {
+ if (_current_shake_pos != _new_shake_pos) {
/* Redraw first the 'black borders' in case of resize */
- if (current_shake_pos < new_shake_pos)
- XFillRectangle(display, window, black_gc, 0, current_shake_pos, window_width, new_shake_pos);
+ if (_current_shake_pos < _new_shake_pos)
+ XFillRectangle(_display,_window, _black_gc, 0, _current_shake_pos, _window_width, _new_shake_pos);
else
- XFillRectangle(display, window, black_gc, 0, window_height - current_shake_pos,
- window_width, window_height - new_shake_pos);
- XShmPutImage(display, window, DefaultGC(display, screen), image,
- 0, 0, scumm_x, scumm_y + new_shake_pos, fb_width, fb_height, 0);
- current_shake_pos = new_shake_pos;
+ XFillRectangle(_display,_window, _black_gc, 0, _window_height - _current_shake_pos,
+ _window_width,_window_height - _new_shake_pos);
+ XShmPutImage(_display, _window, DefaultGC(_display, _screen), _image,
+ 0, 0, _scumm_x, _scumm_y + _new_shake_pos, _fb_width, _fb_height, 0);
+ _current_shake_pos = _new_shake_pos;
} else if (need_redraw == true) {
- XShmPutImage(display, window, DefaultGC(display, screen), image,
- dout.x, dout.y, scumm_x + dout.x, scumm_y + dout.y + current_shake_pos,
+ XShmPutImage(_display, _window, DefaultGC(_display, _screen), _image,
+ dout.x, dout.y, _scumm_x + dout.x, _scumm_y + dout.y + _current_shake_pos,
dout.w - dout.x, dout.h - dout.y, 0);
- XFlush(display);
+ XFlush(_display);
}
}
@@ -682,26 +609,28 @@ void OSystem_X11::quit() {
}
void OSystem_X11::setWindowCaption(const char *caption) {
+ //debug("setWindowCaption('%s')", caption);
}
void OSystem_X11::undraw_mouse() {
- AddDirtyRec(old_state.x, old_state.y, old_state.w, old_state.h);
+ AddDirtyRec(_oldMouseState.x, _oldMouseState.y, _oldMouseState.w, _oldMouseState.h);
}
-void OSystem_X11::draw_mouse(dirty_square *dout) {
+void OSystem_X11::draw_mouse(DirtyRect *dout) {
+ //debug("draw_mouse()");
_mouse_state_changed = false;
if (_mouse_visible == false)
return;
- int xdraw = cur_state.x - cur_state.hot_x;
- int ydraw = cur_state.y - cur_state.hot_y;
- int w = cur_state.w;
- int h = cur_state.h;
+ int xdraw = _curMouseState.x - _curMouseState.hot_x;
+ int ydraw = _curMouseState.y - _curMouseState.hot_y;
+ int w = _curMouseState.w;
+ int h = _curMouseState.h;
int real_w;
int real_h;
- uint16 *dst;
+ uint8 *dst;
const byte *buf = _ms_buf;
if (ydraw < 0) {
@@ -709,17 +638,17 @@ void OSystem_X11::draw_mouse(dirty_square *dout) {
buf += (-ydraw) * w;
ydraw = 0;
} else {
- real_h = (ydraw + h) > fb_height ? (fb_height - ydraw) : h;
+ real_h = (ydraw + h) > _fb_height ? (_fb_height - ydraw) : h;
}
if (xdraw < 0) {
real_w = w + xdraw;
buf += (-xdraw);
xdraw = 0;
} else {
- real_w = (xdraw + w) > fb_width ? (fb_width - xdraw) : w;
+ real_w = (xdraw + w) > _fb_width ? (_fb_width - xdraw) : w;
}
- dst = ((uint16 *) image->data) + (ydraw * fb_width) + xdraw;
+ dst = (uint8 *)_image->data + ((ydraw *_fb_width) + xdraw) * _bytesPerPixel;
if ((real_h == 0) || (real_w == 0)) {
return;
@@ -735,32 +664,36 @@ void OSystem_X11::draw_mouse(dirty_square *dout) {
if ((ydraw + real_h) > dout->h)
dout->h = ydraw + real_h;
- old_state.x = xdraw;
- old_state.y = ydraw;
- old_state.w = real_w;
- old_state.h = real_h;
+ _oldMouseState.x = xdraw;
+ _oldMouseState.y = ydraw;
+ _oldMouseState.w = real_w;
+ _oldMouseState.h = real_h;
while (real_h > 0) {
int width = real_w;
while (width > 0) {
byte color = *buf;
if (color != _mouseKeycolor) {
- *dst = palette[color];
+ if (_depth == 16)
+ *(uint16 *)dst = _palette16[color];
+ else {
+ *(uint32 *)dst = _palette32[color];
+ }
}
buf++;
- dst++;
+ dst += _bytesPerPixel;
width--;
}
buf += w - real_w;
- dst += fb_width - real_w;
+ dst += (_fb_width - real_w) * _bytesPerPixel;
real_h--;
}
}
void OSystem_X11::set_mouse_pos(int x, int y) {
- if ((x != cur_state.x) || (y != cur_state.y)) {
- cur_state.x = x;
- cur_state.y = y;
+ if ((x != _curMouseState.x) || (y != _curMouseState.y)) {
+ _curMouseState.x = x;
+ _curMouseState.y = y;
if (_mouse_state_changed == false) {
undraw_mouse();
}
@@ -772,11 +705,11 @@ void OSystem_X11::warpMouse(int x, int y) {
set_mouse_pos(x, y);
}
-void OSystem_X11::setMouseCursor(const byte *buf, uint w, uint h, int hotspot_x, int hotspot_y, byte keycolor) {
- cur_state.w = w;
- cur_state.h = h;
- cur_state.hot_x = hotspot_x;
- cur_state.hot_y = hotspot_y;
+void OSystem_X11::setMouseCursor(const byte *buf, uint w, uint h, int hotspot_x, int hotspot_y, byte keycolor, int cursorTargetScale) {
+ _curMouseState.w = w;
+ _curMouseState.h = h;
+ _curMouseState.hot_x = hotspot_x;
+ _curMouseState.hot_y = hotspot_y;
if (_ms_buf)
free(_ms_buf);
@@ -791,13 +724,13 @@ void OSystem_X11::setMouseCursor(const byte *buf, uint w, uint h, int hotspot_x,
}
void OSystem_X11::setShakePos(int shake_pos) {
- if (new_shake_pos != shake_pos) {
+ if (_new_shake_pos != shake_pos) {
if (_mouse_state_changed == false) {
undraw_mouse();
}
_mouse_state_changed = true;
}
- new_shake_pos = shake_pos;
+ _new_shake_pos = shake_pos;
}
int OSystem_X11::getOutputSampleRate() const {
@@ -834,10 +767,10 @@ bool OSystem_X11::pollEvent(Event &scumm_event) {
_timer_next_expiry = current_msecs + _timer_duration;
}
- while (XPending(display)) {
+ while (XPending(_display)) {
XEvent event;
- XNextEvent(display, &event);
+ XNextEvent(_display, &event);
switch (event.type) {
case Expose:{
int real_w, real_h;
@@ -846,28 +779,28 @@ bool OSystem_X11::pollEvent(Event &scumm_event) {
real_y = event.xexpose.y;
real_w = event.xexpose.width;
real_h = event.xexpose.height;
- if (real_x < scumm_x) {
- real_w -= scumm_x - real_x;
+ if (real_x < _scumm_x) {
+ real_w -= _scumm_x - real_x;
real_x = 0;
} else {
- real_x -= scumm_x;
+ real_x -= _scumm_x;
}
- if (real_y < scumm_y) {
- real_h -= scumm_y - real_y;
+ if (real_y < _scumm_y) {
+ real_h -= _scumm_y - real_y;
real_y = 0;
} else {
- real_y -= scumm_y;
+ real_y -= _scumm_y;
}
if ((real_h <= 0) || (real_w <= 0))
break;
- if ((real_x >= fb_width) || (real_y >= fb_height))
+ if ((real_x >=_fb_width) || (real_y >=_fb_height))
break;
- if ((real_x + real_w) >= fb_width) {
- real_w = fb_width - real_x;
+ if ((real_x + real_w) >=_fb_width) {
+ real_w =_fb_width - real_x;
}
- if ((real_y + real_h) >= fb_height) {
- real_h = fb_height - real_y;
+ if ((real_y + real_h) >=_fb_height) {
+ real_h =_fb_height - real_y;
}
/* Compute the intersection of the expose event with the real ScummVM display zone */
@@ -907,16 +840,16 @@ bool OSystem_X11::pollEvent(Event &scumm_event) {
break;
case 132:
- report_presses = 0;
+ _report_presses = 0;
break;
case 133:
- fake_right_mouse = 1;
+ _fake_right_mouse = 1;
break;
default:{
KeySym xsym;
- xsym = XKeycodeToKeysym(display, event.xkey.keycode, 0);
+ xsym = XKeycodeToKeysym(_display, event.xkey.keycode, 0);
keycode = xsym;
if ((xsym >= 'a') && (xsym <= 'z') && (event.xkey.state & 0x01))
xsym &= ~0x20; /* Handle shifted keys */
@@ -949,16 +882,16 @@ bool OSystem_X11::pollEvent(Event &scumm_event) {
mode |= KBD_ALT;
switch (event.xkey.keycode) {
case 132: /* 'Q' on the iPAQ */
- report_presses = 1;
+ _report_presses = 1;
break;
case 133: /* Arrow on the iPAQ */
- fake_right_mouse = 0;
+ _fake_right_mouse = 0;
break;
default:{
KeySym xsym;
- xsym = XKeycodeToKeysym(display, event.xkey.keycode, 0);
+ xsym = XKeycodeToKeysym(_display, event.xkey.keycode, 0);
keycode = xsym;
if ((xsym >= 'a') && (xsym <= 'z') && (event.xkey.state & 0x01))
xsym &= ~0x20; /* Handle shifted keys */
@@ -976,51 +909,51 @@ bool OSystem_X11::pollEvent(Event &scumm_event) {
break;
case ButtonPress:
- if (report_presses != 0) {
+ if (_report_presses != 0) {
if (event.xbutton.button == 1) {
- if (fake_right_mouse == 0) {
+ if (_fake_right_mouse == 0) {
scumm_event.type = EVENT_LBUTTONDOWN;
} else {
scumm_event.type = EVENT_RBUTTONDOWN;
}
} else if (event.xbutton.button == 3)
scumm_event.type = EVENT_RBUTTONDOWN;
- scumm_event.mouse.x = event.xbutton.x - scumm_x;
- scumm_event.mouse.y = event.xbutton.y - scumm_y;
+ scumm_event.mouse.x = event.xbutton.x - _scumm_x;
+ scumm_event.mouse.y = event.xbutton.y - _scumm_y;
return true;
}
break;
case ButtonRelease:
- if (report_presses != 0) {
+ if (_report_presses != 0) {
if (event.xbutton.button == 1) {
- if (fake_right_mouse == 0) {
+ if (_fake_right_mouse == 0) {
scumm_event.type = EVENT_LBUTTONUP;
} else {
scumm_event.type = EVENT_RBUTTONUP;
}
} else if (event.xbutton.button == 3)
scumm_event.type = EVENT_RBUTTONUP;
- scumm_event.mouse.x = event.xbutton.x - scumm_x;
- scumm_event.mouse.y = event.xbutton.y - scumm_y;
+ scumm_event.mouse.x = event.xbutton.x - _scumm_x;
+ scumm_event.mouse.y = event.xbutton.y - _scumm_y;
return true;
}
break;
case MotionNotify:
scumm_event.type = EVENT_MOUSEMOVE;
- scumm_event.mouse.x = event.xmotion.x - scumm_x;
- scumm_event.mouse.y = event.xmotion.y - scumm_y;
+ scumm_event.mouse.x = event.xmotion.x - _scumm_x;
+ scumm_event.mouse.y = event.xmotion.y - _scumm_y;
set_mouse_pos(scumm_event.mouse.x, scumm_event.mouse.y);
return true;
case ConfigureNotify:{
- if ((window_width != event.xconfigure.width) || (window_height != event.xconfigure.height)) {
- window_width = event.xconfigure.width;
- window_height = event.xconfigure.height;
- scumm_x = (window_width - fb_width) / 2;
- scumm_y = (window_height - fb_height) / 2;
- XFillRectangle(display, window, black_gc, 0, 0, window_width, window_height);
+ if ((_window_width != event.xconfigure.width) || (_window_height != event.xconfigure.height)) {
+ _window_width = event.xconfigure.width;
+ _window_height = event.xconfigure.height;
+ _scumm_x = (_window_width -_fb_width) / 2;
+ _scumm_y = (_window_height -_fb_height) / 2;
+ XFillRectangle(_display, _window, _black_gc, 0, 0, _window_width, _window_height);
}
}
break;
@@ -1076,37 +1009,40 @@ void OSystem_X11::hideOverlay() {
void OSystem_X11::clearOverlay() {
if (_overlay_visible == false)
return;
- dirty_square d = { 0, 0, fb_width, fb_height };
- AddDirtyRec(0, 0, fb_width, fb_height);
- blit_convert(&d, local_fb_overlay, fb_width);
+ DirtyRect d = { 0, 0, _fb_width, _fb_height };
+ AddDirtyRec(0, 0, _fb_width, _fb_height);
+ blit(&d, _local_fb_overlay, _fb_width);
}
void OSystem_X11::grabOverlay(int16 *dest, int pitch) {
if (_overlay_visible == false)
return;
- dirty_square d = { 0, 0, fb_width, fb_height };
- blit_convert(&d, (uint16 *) dest, pitch);
+ DirtyRect d = { 0, 0, _fb_width, _fb_height };
+ blit(&d, (uint16 *)dest, pitch);
}
void OSystem_X11::copyRectToOverlay(const int16 *src, int pitch, int x, int y, int w, int h) {
if (_overlay_visible == false)
return;
- uint16 *dst = local_fb_overlay + x + (y * fb_width);
+ uint16 *dst = _local_fb_overlay + x + (y * _fb_width);
AddDirtyRec(x, y, w, h);
while (h > 0) {
memcpy(dst, src, w * sizeof(*dst));
- dst += fb_width;
+ dst +=_fb_width;
src += pitch;
h--;
}
}
int16 OSystem_X11::getHeight() {
- return fb_height;
+ return _fb_height;
}
int16 OSystem_X11::getWidth() {
- return fb_width;
+ return _fb_width;
}
+void OSystem_X11::grabPalette(byte *colors, uint start, uint num) {
+ warning("Dummy: grabPalette()");
+}