ANDROID: Support swipe-based virtcontrols

Touching and holding the left side of the screen functions as a
joystick.
Swiping the middle side allows fine control over arrow keys (eg.
dialogues), tapping it sends an enter key.
Swiping the right side up/down sends pageup/pagedown.
This commit is contained in:
Dries Harnie 2013-05-24 01:40:23 +02:00
parent dcfade91e9
commit 471e4748b3
11 changed files with 243 additions and 119 deletions

View file

@ -150,7 +150,9 @@ OSystem_Android::OSystem_Android(int audio_sample_rate, int audio_buffer_size) :
_touchpad_scale(66), _touchpad_scale(66),
_dpad_scale(4), _dpad_scale(4),
_fingersDown(0), _fingersDown(0),
_trackball_scale(2) { _trackball_scale(2),
_joystickPressing(Common::KEYCODE_INVALID),
_arrows_texture(0) {
_fsFactory = new POSIXFilesystemFactory(); _fsFactory = new POSIXFilesystemFactory();
@ -180,8 +182,6 @@ OSystem_Android::OSystem_Android(int audio_sample_rate, int audio_buffer_size) :
for (int i = 0; i < 4; ++i) for (int i = 0; i < 4; ++i)
_activePointers[i] = -1; _activePointers[i] = -1;
_joystickPressing = Common::KEYCODE_INVALID;
} }
OSystem_Android::~OSystem_Android() { OSystem_Android::~OSystem_Android() {
@ -194,6 +194,11 @@ OSystem_Android::~OSystem_Android() {
delete _timerManager; delete _timerManager;
_timerManager = 0; _timerManager = 0;
if (_arrows_texture) {
delete _arrows_texture;
_arrows_texture = 0;
}
deleteMutex(_event_queue_lock); deleteMutex(_event_queue_lock);
} }

View file

@ -252,18 +252,10 @@ private:
kTouchAreaCenter = 0xfffe, kTouchAreaCenter = 0xfffe,
kTouchAreaRight = 0xfffd, kTouchAreaRight = 0xfffd,
kTouchAreaNone = 0xfffc, kTouchAreaNone = 0xfffc,
}; };
uint16 getTouchArea(int x, int y); uint16 getTouchArea(int x, int y);
struct VirtControl {
int x, y;
bool sticky;
Common::KeyCode keyCode;
bool active;
};
struct Pointer { struct Pointer {
uint16 startX, startY; uint16 startX, startY;
uint16 currentX, currentY; uint16 currentX, currentY;
@ -271,16 +263,27 @@ private:
bool active; bool active;
}; };
struct CardinalSwipe {
CardinalSwipe(int dX, int dY);
uint16 distance;
enum Direction {
kDirectionLeft,
kDirectionUp,
kDirectionRight,
kDirectionDown
} direction;
};
enum { kNumPointers = 5 }; enum { kNumPointers = 5 };
static int _virt_numControls;
static VirtControl _virtcontrols[];
int _virt_numDivisions;
Pointer _pointers[kNumPointers]; Pointer _pointers[kNumPointers];
int _activePointers[4]; int _activePointers[4];
Common::KeyCode _joystickPressing; Common::KeyCode _joystickPressing;
int &pointerFor(TouchArea ta); int &pointerFor(TouchArea ta);
const Common::Rect clipFor(const CardinalSwipe &cs);
void initVirtControls(); void initVirtControls();
void drawVirtControls(); void drawVirtControls();
GLESTexture *_arrows_texture;
protected: protected:
// PaletteManager API // PaletteManager API

View file

@ -23,6 +23,7 @@ PATH_DIST = $(srcdir)/dists/android
PATH_RESOURCES = $(PATH_DIST)/res PATH_RESOURCES = $(PATH_DIST)/res
PORT_DISTFILES = $(PATH_DIST)/README.Android PORT_DISTFILES = $(PATH_DIST)/README.Android
DIST_ANDROID_CONTROLS = $(PATH_DIST)/assets/arrows.tga
RESOURCES = \ RESOURCES = \
$(PATH_RESOURCES)/values/strings.xml \ $(PATH_RESOURCES)/values/strings.xml \
@ -121,9 +122,9 @@ $(PATH_STAGE_PREFIX).%/res/drawable/residualvm.png: $(PATH_RESOURCES)/drawable/r
@$(MKDIR) -p $(@D) @$(MKDIR) -p $(@D)
$(CP) $< $@ $(CP) $< $@
$(FILE_RESOURCES_MAIN): $(FILE_MANIFEST) $(RESOURCES) $(ANDROID_JAR) $(DIST_FILES_THEMES) $(DIST_FILES_ENGINEDATA) $(FILE_RESOURCES_MAIN): $(FILE_MANIFEST) $(RESOURCES) $(ANDROID_JAR) $(DIST_FILES_THEMES) $(DIST_FILES_ENGINEDATA) $(DIST_ANDROID_CONTROLS)
$(INSTALL) -d $(PATH_BUILD_ASSETS) $(INSTALL) -d $(PATH_BUILD_ASSETS)
$(INSTALL) -c -m 644 $(DIST_FILES_THEMES) $(DIST_FILES_ENGINEDATA) $(PATH_BUILD_ASSETS)/ $(INSTALL) -c -m 644 $(DIST_FILES_THEMES) $(DIST_FILES_ENGINEDATA) $(DIST_ANDROID_CONTROLS) $(PATH_BUILD_ASSETS)/
work_dir=`pwd`; \ work_dir=`pwd`; \
for i in $(PATH_BUILD_ASSETS)/*.zip; do \ for i in $(PATH_BUILD_ASSETS)/*.zip; do \
echo "recompress $$i"; \ echo "recompress $$i"; \

View file

@ -235,6 +235,25 @@ static Common::KeyCode determineKey(int dX, int dY) {
return Common::KEYCODE_INVALID; return Common::KEYCODE_INVALID;
} }
OSystem_Android::CardinalSwipe::CardinalSwipe(int dX, int dY) {
if (abs(dX) > abs(dY)) {
if (dX > 0) {
distance = dX;
direction = kDirectionRight;
} else {
distance = abs(dX);
direction = kDirectionLeft;
}
} else {
if (dY > 0) {
distance = dY;
direction = kDirectionDown;
} else {
distance = abs(dY);
direction = kDirectionUp;
}
}
}
static const int kQueuedInputEventDelay = 50; static const int kQueuedInputEventDelay = 50;
@ -328,28 +347,7 @@ void OSystem_Android::updateEventScale() {
_eventScaleX = 100 * 640 / tex->width(); _eventScaleX = 100 * 640 / tex->width();
} }
int OSystem_Android::_virt_numControls = 6;
OSystem_Android::VirtControl OSystem_Android::_virtcontrols[] = {
{-2, 1, false, Common::KEYCODE_u, false},
{-3, 1, false, Common::KEYCODE_p, false},
{-1, 5, false, Common::KEYCODE_i, false},
{-1, 0, false, Common::KEYCODE_PAGEDOWN, false},
{-1, 1, false, Common::KEYCODE_KP_ENTER, false},
{-1, 2, false, Common::KEYCODE_PAGEUP, false},
};
uint16 OSystem_Android::getTouchArea(int x, int y) { uint16 OSystem_Android::getTouchArea(int x, int y) {
int scaledX = _virt_numDivisions * x / _egl_surface_width;
int scaledY = _virt_numDivisions * (_egl_surface_height - y) / _egl_surface_height;
for (uint16 i = 0; i < _virt_numControls; ++i) {
int testX = _virtcontrols[i].x < 0
? (_virtcontrols[i].x + _virt_numDivisions)
: _virtcontrols[i].x;
if (scaledX == testX && scaledY == _virtcontrols[i].y)
return i;
}
float xPercent = float(x) / _egl_surface_width; float xPercent = float(x) / _egl_surface_width;
if (xPercent < 0.3) if (xPercent < 0.3)
@ -707,8 +705,6 @@ void OSystem_Android::pushEvent(int type, int arg1, int arg2, int arg3,
if (idx == kTouchAreaCenter) { if (idx == kTouchAreaCenter) {
e.kbd.keycode = Common::KEYCODE_RETURN; e.kbd.keycode = Common::KEYCODE_RETURN;
e.kbd.ascii = Common::ASCII_RETURN; e.kbd.ascii = Common::ASCII_RETURN;
} else {
e.kbd.keycode = _virtcontrols[idx].keyCode;
} }
lockMutex(_event_queue_lock); lockMutex(_event_queue_lock);
@ -813,9 +809,6 @@ void OSystem_Android::pushEvent(int type, int arg1, int arg2, int arg3,
_pointers[arg1].startX = _pointers[arg1].currentX = arg3; _pointers[arg1].startX = _pointers[arg1].currentX = arg3;
_pointers[arg1].startY = _pointers[arg1].currentY = arg4; _pointers[arg1].startY = _pointers[arg1].currentY = arg4;
} }
if (touchArea == kTouchAreaJoystick)
LOGW("Started joystick move at (%d,%d)", arg3, arg4);
} }
return; return;
@ -839,7 +832,6 @@ void OSystem_Android::pushEvent(int type, int arg1, int arg2, int arg3,
_joystickPressing = newPressing; _joystickPressing = newPressing;
} }
LOGW("Joystick moved to (%d,%d)", arg3, arg4);
} }
} }
return; return;
@ -880,34 +872,36 @@ void OSystem_Android::pushEvent(int type, int arg1, int arg2, int arg3,
unlockMutex(_event_queue_lock); unlockMutex(_event_queue_lock);
} else { } else {
_pointers[arg1].active = false;
int dX = _pointers[arg1].currentX - _pointers[arg1].startX; int dX = _pointers[arg1].currentX - _pointers[arg1].startX;
int dY = _pointers[arg1].currentY - _pointers[arg1].startY; int dY = _pointers[arg1].currentY - _pointers[arg1].startY;
struct CardinalSwipe cs(dX, dY);
switch (_pointers[arg1].function) { switch (_pointers[arg1].function) {
case kTouchAreaCenter: { case kTouchAreaCenter: {
pointerFor(kTouchAreaCenter) = -1; pointerFor(kTouchAreaCenter) = -1;
if (abs(dX) < 100 && abs(dY) < 100) { if (cs.distance < 100) {
sendKey(Common::KEYCODE_u); sendKey(Common::KEYCODE_RETURN);
} else if (abs(dX) > abs(dY)) { break;
if (dX > 0) { }
sendKey(Common::KEYCODE_RIGHT); switch (cs.direction) {
} else { case CardinalSwipe::kDirectionLeft:
sendKey(Common::KEYCODE_LEFT); sendKey(Common::KEYCODE_LEFT);
} break;
} else { case CardinalSwipe::kDirectionUp:
if (dY > 0) { sendKey(Common::KEYCODE_UP);
sendKey(Common::KEYCODE_DOWN); break;
} else { case CardinalSwipe::kDirectionRight:
sendKey(Common::KEYCODE_UP); sendKey(Common::KEYCODE_RIGHT);
} break;
case CardinalSwipe::kDirectionDown:
sendKey(Common::KEYCODE_DOWN);
break;
} }
break; break;
} }
case kTouchAreaJoystick: case kTouchAreaJoystick:
pointerFor(kTouchAreaJoystick) = -1; pointerFor(kTouchAreaJoystick) = -1;
LOGW("Joystick move ended at (%d,%d)", arg3, arg4);
if (_joystickPressing != Common::KEYCODE_INVALID) { if (_joystickPressing != Common::KEYCODE_INVALID) {
lockMutex(_event_queue_lock); lockMutex(_event_queue_lock);
e.kbd.keycode = _joystickPressing; e.kbd.keycode = _joystickPressing;
@ -919,13 +913,15 @@ void OSystem_Android::pushEvent(int type, int arg1, int arg2, int arg3,
case kTouchAreaRight: case kTouchAreaRight:
pointerFor(kTouchAreaRight) = -1; pointerFor(kTouchAreaRight) = -1;
if (abs(dX) > 50 || abs(dY) < 100) { if ( cs.direction == CardinalSwipe::kDirectionLeft
|| cs.direction == CardinalSwipe::kDirectionRight
|| cs.distance < 100) {
sendKey(Common::KEYCODE_i); sendKey(Common::KEYCODE_i);
} else { } else {
if (dY > 0) { if (cs.direction == CardinalSwipe::kDirectionUp) {
sendKey(Common::KEYCODE_PAGEDOWN);
} else {
sendKey(Common::KEYCODE_PAGEUP); sendKey(Common::KEYCODE_PAGEUP);
} else {
sendKey(Common::KEYCODE_PAGEDOWN);
} }
} }
break; break;
@ -934,6 +930,7 @@ void OSystem_Android::pushEvent(int type, int arg1, int arg2, int arg3,
default: default:
break; break;
} }
_pointers[arg1].active = false;
_pointers[arg1].function = kTouchAreaNone; _pointers[arg1].function = kTouchAreaNone;
} }
return; return;

View file

@ -41,6 +41,7 @@
#include "common/endian.h" #include "common/endian.h"
#include "graphics/conversion.h" #include "graphics/conversion.h"
#include "graphics/decoders/tga.h"
#include "graphics/opengles2/shader.h" #include "graphics/opengles2/shader.h"
#include "backends/platform/android/android.h" #include "backends/platform/android/android.h"
@ -569,57 +570,82 @@ void OSystem_Android::updateScreen() {
} }
static Graphics::Shader *_virtcontrols_shader = NULL; static GLES8888Texture *loadBuiltinTexture(const char *filename) {
static const char *_virtVertex = Common::ArchiveMemberPtr member = SearchMan.getMember(filename);
"#version 100\n" Common::SeekableReadStream *str = member->createReadStream();
"attribute vec2 position;\n" Graphics::TGADecoder dec;
"uniform vec2 offsetXY;\n" dec.loadStream(*str);
"uniform vec2 sizeWH;\n" void *pixels = dec.getSurface()->pixels;
"void main() {\n"
"vec2 pos = offsetXY + position * sizeWH;\n"
"pos.x = pos.x * 2.0 - 1.0;\n"
"pos.y = pos.y * 2.0 - 1.0;\n"
"gl_Position = vec4(pos, 0.0, 1.0);\n"
"}\n";
static const char *_virtFragment = GLES8888Texture *ret = new GLES8888Texture();
"#version 100\n" uint16 w = dec.getSurface()->w;
"precision mediump float;\n" uint16 h = dec.getSurface()->h;
"uniform bool active;\n" uint16 pitch = dec.getSurface()->pitch;
"void main() {\n" ret->allocBuffer(w, h);
"gl_FragColor = vec4(1.0, 1.0, 1.0, active ? 0.8 : 0.3);\n" ret->updateBuffer(0, 0, w, h, pixels, pitch);
"}\n";
delete str;
return ret;
}
void OSystem_Android::initVirtControls() { void OSystem_Android::initVirtControls() {
if (_virtcontrols_shader) if (!_arrows_texture)
return; _arrows_texture = loadBuiltinTexture("arrows.tga");
}
const char* attributes[] = { "position", NULL }; const Common::Rect OSystem_Android::clipFor(const CardinalSwipe &cs) {
_virtcontrols_shader = Graphics::Shader::fromStrings("key", _virtVertex, _virtFragment, attributes); switch (cs.direction) {
_virtcontrols_shader->enableVertexAttribute("position", g_verticesVBO, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float), 0); case CardinalSwipe::kDirectionLeft:
_virt_numDivisions = _egl_surface_width > 800 ? 12 : 8; return Common::Rect(0, 128, 128, 256);
case CardinalSwipe::kDirectionUp:
return Common::Rect(0, 0, 128, 128);
case CardinalSwipe::kDirectionRight:
return Common::Rect(128, 128, 256, 256);
case CardinalSwipe::kDirectionDown:
return Common::Rect(128, 0, 256, 128);
default: // unreachable
return Common::Rect(0, 0, 1, 1);
}
} }
void OSystem_Android::drawVirtControls() { void OSystem_Android::drawVirtControls() {
if (_show_overlay) if (_show_overlay)
return; return;
_virtcontrols_shader->use();
float div = 1.0 / _virt_numDivisions;
float divX = div;
float divY = div;
_virtcontrols_shader->setUniform("sizeWH", 0.9 * Math::Vector2d(divX, divY));
glEnable(GL_BLEND); int joyPtr = pointerFor(kTouchAreaJoystick);
if (joyPtr != -1) {
Pointer &joy = _pointers[joyPtr];
CardinalSwipe cs(joy.currentX - joy.startX, joy.currentY - joy.startY);
for (int control = 0; control < _virt_numControls; ++control) { if (cs.distance >= 50) {
float offsetX = (_virtcontrols[control].x + 0.1) * divX; Common::Rect clip = clipFor(cs);
float offsetY = (_virtcontrols[control].y + 0.1) * divY; _arrows_texture->drawTexture(2 * _egl_surface_width / 10, _egl_surface_height / 2, 64, 64, clip);
if (offsetX < 0) }
offsetX += 1.0; }
_virtcontrols_shader->setUniform("offsetXY", Math::Vector2d(offsetX, offsetY)); int centerPtr = pointerFor(kTouchAreaCenter);
_virtcontrols_shader->setUniform("active", _virtcontrols[control].active); if (centerPtr != -1) {
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); Pointer &center = _pointers[centerPtr];
CardinalSwipe cs(center.currentX - center.startX, center.currentY - center.startY);
if (cs.distance >= 100) {
Common::Rect clip = clipFor(cs);
_arrows_texture->drawTexture(_egl_surface_width / 2, _egl_surface_height / 2, 64, 64, clip);
}
}
int rightPtr = pointerFor(kTouchAreaRight);
if (rightPtr != -1) {
Pointer &right = _pointers[rightPtr];
CardinalSwipe cs(right.currentX - right.startX, right.currentY - right.startY);
if (cs.distance >= 100) {
if ( cs.direction == CardinalSwipe::kDirectionDown
|| cs.direction == CardinalSwipe::kDirectionUp) {
Common::Rect clip = clipFor(cs);
_arrows_texture->drawTexture( 8 * _egl_surface_width / 10, _egl_surface_height / 2, 64, 64, clip);
}
}
} }
} }

View file

@ -97,7 +97,7 @@ void GLESBaseTexture::initGL() {
} }
const char* attributes[] = { "position", "texcoord", NULL }; const char* attributes[] = { "position", "texcoord", NULL };
g_box_shader = Graphics::Shader::fromStrings("box", Graphics::BuiltinShaders::boxVertex, Graphics::BuiltinShaders::boxFragment, attributes); g_box_shader = Graphics::Shader::fromStrings("control", Graphics::BuiltinShaders::controlVertex, Graphics::BuiltinShaders::controlFragment, attributes);
g_verticesVBO = Graphics::Shader::createBuffer(GL_ARRAY_BUFFER, sizeof(vertices), vertices); g_verticesVBO = Graphics::Shader::createBuffer(GL_ARRAY_BUFFER, sizeof(vertices), vertices);
g_box_shader->enableVertexAttribute("position", g_verticesVBO, 2, GL_FLOAT, GL_TRUE, 2 * sizeof(float), 0); g_box_shader->enableVertexAttribute("position", g_verticesVBO, 2, GL_FLOAT, GL_TRUE, 2 * sizeof(float), 0);
g_box_shader->enableVertexAttribute("texcoord", g_verticesVBO, 2, GL_FLOAT, GL_TRUE, 2 * sizeof(float), 0); g_box_shader->enableVertexAttribute("texcoord", g_verticesVBO, 2, GL_FLOAT, GL_TRUE, 2 * sizeof(float), 0);
@ -186,7 +186,7 @@ void GLESBaseTexture::allocBuffer(GLuint w, GLuint h) {
initSize(); initSize();
} }
void GLESBaseTexture::drawTexture(GLshort x, GLshort y, GLshort w, GLshort h) { void GLESBaseTexture::drawTexture(GLshort x, GLshort y, GLshort w, GLshort h, const Common::Rect &clip) {
// LOGD("*** Texture %p: Drawing %dx%d rect to (%d,%d)", this, w, h, x, y); // LOGD("*** Texture %p: Drawing %dx%d rect to (%d,%d)", this, w, h, x, y);
assert(g_box_shader); assert(g_box_shader);
@ -197,13 +197,14 @@ void GLESBaseTexture::drawTexture(GLshort x, GLshort y, GLshort w, GLshort h) {
const GLfloat offsetY = float(y) / float(JNI::egl_surface_height); const GLfloat offsetY = float(y) / float(JNI::egl_surface_height);
const GLfloat sizeW = float(w) / float(JNI::egl_surface_width); const GLfloat sizeW = float(w) / float(JNI::egl_surface_width);
const GLfloat sizeH = float(h) / float(JNI::egl_surface_height); const GLfloat sizeH = float(h) / float(JNI::egl_surface_height);
const GLfloat tex_width = float(_surface.w) / float(_texture_width); Math::Vector4d clipV = Math::Vector4d(clip.left, clip.top, clip.right, clip.bottom);
const GLfloat tex_height = float(_surface.h) / float(_texture_height); clipV.x() /= _texture_width; clipV.y() /= _texture_height;
clipV.z() /= _texture_width; clipV.w() /= _texture_height;
// LOGD("*** Drawing at (%f,%f) , size %f x %f", float(x) / float(_surface.w), float(y) / float(_surface.h), tex_width, tex_height); // LOGD("*** Drawing at (%f,%f) , size %f x %f", float(x) / float(_surface.w), float(y) / float(_surface.h), tex_width, tex_height);
g_box_shader->setUniform("offsetXY", Math::Vector2d(offsetX, offsetY)); g_box_shader->setUniform("offsetXY", Math::Vector2d(offsetX, offsetY));
g_box_shader->setUniform("sizeWH", Math::Vector2d(sizeW, sizeH)); g_box_shader->setUniform("sizeWH", Math::Vector2d(sizeW, sizeH));
g_box_shader->setUniform("texcrop", Math::Vector2d(tex_width, tex_height)); g_box_shader->setUniform("clip", clipV);
g_box_shader->setUniform("flipY", !_is_game_texture); g_box_shader->setUniform("flipY", !_is_game_texture);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
@ -281,7 +282,7 @@ void GLESTexture::fillBuffer(uint32 color) {
setDirty(); setDirty();
} }
void GLESTexture::drawTexture(GLshort x, GLshort y, GLshort w, GLshort h) { void GLESTexture::drawTexture(GLshort x, GLshort y, GLshort w, GLshort h, const Common::Rect &clip) {
if (_all_dirty) { if (_all_dirty) {
_dirty_rect.top = 0; _dirty_rect.top = 0;
_dirty_rect.left = 0; _dirty_rect.left = 0;
@ -323,7 +324,7 @@ void GLESTexture::drawTexture(GLshort x, GLshort y, GLshort w, GLshort h) {
dwidth, dheight, _glFormat, _glType, _tex)); dwidth, dheight, _glFormat, _glType, _tex));
} }
GLESBaseTexture::drawTexture(x, y, w, h); GLESBaseTexture::drawTexture(x, y, w, h, clip);
} }
GLES4444Texture::GLES4444Texture() : GLES4444Texture::GLES4444Texture() :
@ -333,6 +334,13 @@ GLES4444Texture::GLES4444Texture() :
GLES4444Texture::~GLES4444Texture() { GLES4444Texture::~GLES4444Texture() {
} }
GLES8888Texture::GLES8888Texture() :
GLESTexture(GL_RGBA, GL_UNSIGNED_BYTE, pixelFormat()) {
}
GLES8888Texture::~GLES8888Texture() {
}
GLES5551Texture::GLES5551Texture() : GLES5551Texture::GLES5551Texture() :
GLESTexture(GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, pixelFormat()) { GLESTexture(GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, pixelFormat()) {
} }
@ -419,8 +427,7 @@ void GLESFakePaletteTexture::updateBuffer(GLuint x, GLuint y, GLuint w,
} while (--h); } while (--h);
} }
void GLESFakePaletteTexture::drawTexture(GLshort x, GLshort y, GLshort w, void GLESFakePaletteTexture::drawTexture(GLshort x, GLshort y, GLshort w, GLshort h, const Common::Rect &clip) {
GLshort h) {
if (_all_dirty) { if (_all_dirty) {
_dirty_rect.top = 0; _dirty_rect.top = 0;
_dirty_rect.left = 0; _dirty_rect.left = 0;
@ -452,7 +459,7 @@ void GLESFakePaletteTexture::drawTexture(GLshort x, GLshort y, GLshort w,
dwidth, dheight, _glFormat, _glType, _buf)); dwidth, dheight, _glFormat, _glType, _buf));
} }
GLESBaseTexture::drawTexture(x, y, w, h); GLESBaseTexture::drawTexture(x, y, w, h, clip);
} }
const Graphics::PixelFormat &GLESFakePaletteTexture::getPixelFormat() const { const Graphics::PixelFormat &GLESFakePaletteTexture::getPixelFormat() const {

View file

@ -57,7 +57,11 @@ public:
const void *buf, int pitch_buf) = 0; const void *buf, int pitch_buf) = 0;
virtual void fillBuffer(uint32 color) = 0; virtual void fillBuffer(uint32 color) = 0;
virtual void drawTexture(GLshort x, GLshort y, GLshort w, GLshort h); virtual void drawTexture(GLshort x, GLshort y, GLshort w, GLshort h) {
drawTexture(x, y, w, h, Common::Rect(0, 0, width(), height()));
}
virtual void drawTexture(GLshort x, GLshort y, GLshort w, GLshort h, const Common::Rect &clip);
inline void setDrawRect(const Common::Rect &rect) { inline void setDrawRect(const Common::Rect &rect) {
_draw_rect = rect; _draw_rect = rect;
@ -203,13 +207,26 @@ public:
const void *buf, int pitch_buf); const void *buf, int pitch_buf);
virtual void fillBuffer(uint32 color); virtual void fillBuffer(uint32 color);
virtual void drawTexture(GLshort x, GLshort y, GLshort w, GLshort h); virtual void drawTexture(GLshort x, GLshort y, GLshort w, GLshort h) {
drawTexture(x, y, w, h, Common::Rect(0, 0, width(), height()));
}
virtual void drawTexture(GLshort x, GLshort y, GLshort w, GLshort h, const Common::Rect &clip);
protected: protected:
byte *_pixels; byte *_pixels;
byte *_buf; byte *_buf;
}; };
class GLES8888Texture : public GLESTexture {
public:
GLES8888Texture();
virtual ~GLES8888Texture();
static Graphics::PixelFormat pixelFormat() {
return Graphics::PixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0);
}
};
// RGBA4444 texture // RGBA4444 texture
class GLES4444Texture : public GLESTexture { class GLES4444Texture : public GLESTexture {
public: public:
@ -256,7 +273,10 @@ public:
const void *buf, int pitch_buf); const void *buf, int pitch_buf);
virtual void fillBuffer(uint32 color); virtual void fillBuffer(uint32 color);
virtual void drawTexture(GLshort x, GLshort y, GLshort w, GLshort h); virtual void drawTexture(GLshort x, GLshort y, GLshort w, GLshort h) {
drawTexture(x, y, w, h, Common::Rect(0, 0, width(), height()));
}
virtual void drawTexture(GLshort x, GLshort y, GLshort w, GLshort h, const Common::Rect &clip);
virtual const byte *palette_const() const { virtual const byte *palette_const() const {
return (byte *)_palette; return (byte *)_palette;

Binary file not shown.

After

Width:  |  Height:  |  Size: 256 KiB

View file

@ -23,6 +23,7 @@ MODULE_OBJS := \
pixelbuffer.o \ pixelbuffer.o \
opengles2/shader.o \ opengles2/shader.o \
opengles2/box_shaders.o \ opengles2/box_shaders.o \
opengles2/control_shaders.o \
opengles2/compat_shaders.o \ opengles2/compat_shaders.o \
tinygl/api.o \ tinygl/api.o \
tinygl/arrays.o \ tinygl/arrays.o \

View file

@ -0,0 +1,65 @@
/* ResidualVM - A 3D game interpreter
*
* ResidualVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program 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 General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
#include "common/scummsys.h"
#ifdef USE_GLES2
namespace Graphics {
namespace BuiltinShaders {
const char *controlVertex =
"#version 100\n"
"attribute vec2 position;\n"
"attribute vec2 texcoord;\n"
"uniform vec2 offsetXY;\n"
"uniform vec2 sizeWH;\n"
"uniform vec4 clip;\n"
"uniform bool flipY;\n"
"varying vec2 Texcoord;\n"
"void main() {\n"
"Texcoord = clip.xy + texcoord * (clip.zw - clip.xy);\n"
"vec2 pos = offsetXY + position * sizeWH;\n"
"pos.x = pos.x * 2.0 - 1.0;\n"
"pos.y = pos.y * 2.0 - 1.0;\n"
"if (flipY)\n"
"pos.y *= -1.0;\n"
"gl_Position = vec4(pos, 0.0, 1.0);\n"
"}\n";
const char *controlFragment =
"#version 100\n"
"#ifdef GL_FRAGMENT_PRECISION_HIGH\n"
"precision highp float;\n"
"#else\n"
"precision mediump float;\n"
"#endif\n"
"varying vec2 Texcoord;\n"
"uniform sampler2D tex;\n"
"void main() {\n"
"gl_FragColor = texture2D(tex, Texcoord);\n"
"}\n";
}
}
#endif

View file

@ -34,10 +34,9 @@
namespace Graphics { namespace Graphics {
namespace BuiltinShaders { namespace BuiltinShaders {
extern const char *boxVertex; extern const char *boxVertex, *boxFragment;
extern const char *boxFragment; extern const char *compatVertex, *compatFragment;
extern const char *compatVertex; extern const char *controlVertex, *controlFragment;
extern const char *compatFragment;
} }
struct VertexAttrib { struct VertexAttrib {