From 5068d08ebb7ba029d1cdbc3eb121bf4945f89d86 Mon Sep 17 00:00:00 2001 From: Oystein Eftevaag Date: Wed, 5 Dec 2007 08:03:47 +0000 Subject: ARM ASM blitting routines from Robin_Watts svn-id: r29717 --- backends/platform/iphone/blit_arm.h | 38 +++++++++ backends/platform/iphone/blit_arm.s | 140 +++++++++++++++++++++++++++++++ backends/platform/iphone/module.mk | 3 +- backends/platform/iphone/osys_iphone.cpp | 88 +++++++++++++------ 4 files changed, 244 insertions(+), 25 deletions(-) create mode 100644 backends/platform/iphone/blit_arm.h create mode 100644 backends/platform/iphone/blit_arm.s (limited to 'backends/platform/iphone') diff --git a/backends/platform/iphone/blit_arm.h b/backends/platform/iphone/blit_arm.h new file mode 100644 index 0000000000..2a363630d8 --- /dev/null +++ b/backends/platform/iphone/blit_arm.h @@ -0,0 +1,38 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM 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. + * + * $URL$ + * $Id$ + * + */ + +extern "C" void blitLandscapeScreenRect16bpp(uint16 *dst, uint16 *src, + int width, + int height, + int screenWidth, + int screenHeight); + +extern "C" void blitLandscapeScreenRect8bpp(uint16 *dst, + byte *src, + int width, + int height, + uint16 *palette, + int screenWidth, + int screenHeight); diff --git a/backends/platform/iphone/blit_arm.s b/backends/platform/iphone/blit_arm.s new file mode 100644 index 0000000000..ae31fdcce4 --- /dev/null +++ b/backends/platform/iphone/blit_arm.s @@ -0,0 +1,140 @@ +@ ScummVM - Graphic Adventure Engine +@ +@ ScummVM 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. +@ +@ $URL$ +@ $Id$ +@ +@ @author Robin Watts (robin@wss.co.uk) + + .text + + .global _blitLandscapeScreenRect16bpp + .global _blitLandscapeScreenRect8bpp + + +_blitLandscapeScreenRect16bpp: + @ r0 = dst + @ r1 = src + @ r2 = w + @ r3 = h + @ <> = _screenWidth + @ <> = _screenHeight + MOV r12,r13 + STMFD r13!,{r4-r11,r14} + LDMFD r12,{r12,r14} @ r12 = _screenWidth + @ r14 = _screenHeight + ADD r14,r14,r3 @ r14 = _screenHeight + h + MVN r11,#0 + MLA r11,r3,r12,r11 @ r11= _screenWidth*h-1 + ADD r12,r12,r12 +xloop: + SUBS r4,r3,#5 @ r4 = y = h + BLE thin +yloop: + LDRH r5, [r1],r12 @ r5 = *src src += _screenWidth + LDRH r6, [r1],r12 @ r6 = *src src += _screenWidth + LDRH r7, [r1],r12 @ r7 = *src src += _screenWidth + LDRH r8, [r1],r12 @ r8 = *src src += _screenWidth + LDRH r9, [r1],r12 @ r9 = *src src += _screenWidth + LDRH r10,[r1],r12 @ r10= *src src += _screenWidth + SUBS r4,r4,#6 + STRH r5, [r0],#2 @ *dst++ = r5 + STRH r6, [r0],#2 @ *dst++ = r6 + STRH r7, [r0],#2 @ *dst++ = r7 + STRH r8, [r0],#2 @ *dst++ = r8 + STRH r9, [r0],#2 @ *dst++ = r9 + STRH r10,[r0],#2 @ *dst++ = r10 + BGT yloop +thin: + ADDS r4,r4,#5 + BEQ lineend +thin_loop: + LDRH r5,[r1],r12 @ r5 = *src src += _screenWidth + SUBS r4,r4,#1 + STRH r5,[r0],#2 @ *dst++ = r5 + BGT thin_loop +lineend: + SUB r0,r0,r14,LSL #1 @ dst -= _screenHeight + h + SUB r1,r1,r11,LSL #1 @ src += 1-_screenWidth*h + SUBS r2,r2,#1 + BGT xloop + + LDMFD r13!,{r4-r11,PC} + +_blitLandscapeScreenRect8bpp: + @ r0 = dst + @ r1 = src + @ r2 = w + @ r3 = h + @ <> = _palette + @ <> = _screenWidth + @ <> = _screenHeight + MOV r12,r13 + STMFD r13!,{r4-r11,r14} + LDMFD r12,{r11,r12,r14} @ r11 = _palette + @ r12 = _screenWidth + @ r14 = _screenHeight + ADD r14,r14,r3 @ r14 = _screenHeight + h + MVN r6,#0 + MLA r6,r3,r12,r6 @ r6 = _screenWidth*h-1 +xloop8: + MOV r4,r3 @ r4 = y = h + SUBS r4,r3,#4 @ r4 = y = h + BLE thin8 +yloop8: + LDRB r5, [r1],r12 @ r5 = *src src += _screenWidth + LDRB r7, [r1],r12 @ r7 = *src src += _screenWidth + LDRB r8, [r1],r12 @ r8 = *src src += _screenWidth + LDRB r9, [r1],r12 @ r9 = *src src += _screenWidth + LDRB r10,[r1],r12 @ r10= *src src += _screenWidth + ADD r5, r5, r5 + ADD r7, r7, r7 + ADD r8, r8, r8 + ADD r9, r9, r9 + ADD r10,r10,r10 + LDRH r5, [r11,r5] + LDRH r7, [r11,r7] + LDRH r8, [r11,r8] + LDRH r9, [r11,r9] + LDRH r10,[r11,r10] + SUBS r4,r4,#5 + STRH r5, [r0],#2 @ *dst++ = r5 + STRH r7, [r0],#2 @ *dst++ = r7 + STRH r8, [r0],#2 @ *dst++ = r8 + STRH r9, [r0],#2 @ *dst++ = r9 + STRH r10,[r0],#2 @ *dst++ = r10 + BGT yloop8 +thin8: + ADDS r4,r4,#4 + BEQ lineend8 +thin_loop8: + LDRB r5,[r1],r12 @ r5 = *src src += _screenWidth + ADD r5,r5,r5 + LDRH r5,[r11,r5] + SUBS r4,r4,#1 + STRH r5,[r0],#2 @ *dst++ = r5 + BGT thin_loop8 +lineend8: + SUB r0,r0,r14,LSL #1 @ dst -= _screenHeight + h + SUB r1,r1,r6 @ src += 1-_screenWidth*h + SUBS r2,r2,#1 + BGT xloop8 + + LDMFD r13!,{r4-r11,PC} diff --git a/backends/platform/iphone/module.mk b/backends/platform/iphone/module.mk index 47461ad2b2..311a0490c5 100644 --- a/backends/platform/iphone/module.mk +++ b/backends/platform/iphone/module.mk @@ -4,7 +4,8 @@ MODULE_OBJS := \ osys_iphone.o \ iphone_main.o \ iphone_video.o \ - iphone_keyboard.o + iphone_keyboard.o \ + blit_arm.o MODULE_DIRS += \ backends/platform/iphone/ diff --git a/backends/platform/iphone/osys_iphone.cpp b/backends/platform/iphone/osys_iphone.cpp index 715131961c..e0334d9778 100644 --- a/backends/platform/iphone/osys_iphone.cpp +++ b/backends/platform/iphone/osys_iphone.cpp @@ -47,6 +47,7 @@ #include "osys_iphone.h" #include "iphone_common.h" +#include "blit_arm.h" const OSystem::GraphicsMode OSystem_IPHONE::s_supportedGraphicsModes[] = { {0, 0, 0} @@ -298,32 +299,61 @@ void OSystem_IPHONE::internUpdateScreen() { while (_dirtyRects.size()) { Common::Rect dirtyRect = _dirtyRects.remove_at(_dirtyRects.size() - 1); + //printf("Drawing: (%i, %i) -> (%i, %i)\n", dirtyRect.left, dirtyRect.top, dirtyRect.right, dirtyRect.bottom); - int row; + int row; if (_overlayVisible) { - for (int x = dirtyRect.left; x < dirtyRect.right; x++) { - if (landscapeMode) { - row = (_screenWidth - x - 1) * _screenHeight; - for (int y = dirtyRect.top; y < dirtyRect.bottom; y++) - _fullscreen[row + y] = _overlayBuffer[y * _screenWidth + x]; - } else { - for (int y = dirtyRect.top; y < dirtyRect.bottom; y++) - _fullscreen[y * _screenWidth + x] = _overlayBuffer[y * _screenWidth + x]; + if (landscapeMode) { + uint16 *src = (uint16 *)&_overlayBuffer[dirtyRect.top * _screenWidth + dirtyRect.left]; + uint16 *dst = &_fullscreen[(_screenWidth - dirtyRect.left - 1) * _screenHeight + dirtyRect.top]; + int h = dirtyRect.bottom - dirtyRect.top; + // for (int x = dirtyRect.right-dirtyRect.left; x > 0; x--) { + // for (int y = h; y > 0; y--) { + // *dst++ = *src; + // src += _screenWidth; + // } + // dst -= _screenHeight + h; + // src += 1 - h * _screenWidth; + // } + blitLandscapeScreenRect16bpp(dst, src, dirtyRect.right - dirtyRect.left, h, _screenWidth, _screenHeight); + } else { + uint16 *src = (uint16 *)&_overlayBuffer[dirtyRect.top * _screenWidth + dirtyRect.left]; + uint16 *dst = &_fullscreen[dirtyRect.top * _screenWidth + dirtyRect.left]; + int x = (dirtyRect.right - dirtyRect.left) * 2; + for (int y = dirtyRect.bottom - dirtyRect.top; y > 0; y--) { + memcpy(dst, src, x); + src += _screenWidth; + dst += _screenWidth; } } } else { - for (int x = dirtyRect.left; x < dirtyRect.right; x++) { - if (landscapeMode) { - row = (_screenWidth - x - 1) * _screenHeight; - for (int y = dirtyRect.top; y < dirtyRect.bottom; y++) - _fullscreen[row + y] = _palette[_offscreen[y * _screenWidth + x]]; - } else { - for (int y = dirtyRect.top; y < dirtyRect.bottom; y++) - _fullscreen[y * _screenWidth + x] = _palette[_offscreen[y * _screenWidth + x]]; + if (landscapeMode) { + byte *src = &_offscreen[dirtyRect.top * _screenWidth + dirtyRect.left]; + uint16 *dst = &_fullscreen[(_screenWidth - dirtyRect.left - 1) * _screenHeight + dirtyRect.top]; + int h = dirtyRect.bottom - dirtyRect.top; + // for (int x = dirtyRect.right - dirtyRect.left; x > 0; x--) { + // for (int y = h; y > 0; y--) { + // *dst++ = _palette[*src]; + // src += _screenWidth; + // } + // dst -= _screenHeight + h; + // src += 1 - h * _screenWidth; + // } + blitLandscapeScreenRect8bpp(dst, src, dirtyRect.right - dirtyRect.left, h, _palette, _screenWidth, _screenHeight); + } else { + byte *src = &_offscreen[dirtyRect.top * _screenWidth + dirtyRect.left]; + uint16 *dst = &_fullscreen[dirtyRect.top * _screenWidth + dirtyRect.left]; + int width = dirtyRect.right - dirtyRect.left; + for (int y = dirtyRect.bottom - dirtyRect.top; y > 0; y--) { + for (int x = width; x > 0; x--) { + *dst++ = _palette[*src++]; + } + dst += _screenWidth - width; + src += _screenWidth - width; } } } - + //draw mouse on top int mx, my; if (_mouseVisible && dirtyRect.intersects(mouseRect)) { @@ -354,15 +384,23 @@ void OSystem_IPHONE::internUpdateScreen() { else { if (landscapeMode) { int height = (dirtyRect.bottom - dirtyRect.top) * 2 ; - for (int x = dirtyRect.left; x < dirtyRect.right; x++) { - int offset = ((_screenWidth - x - 1) * _screenHeight + dirtyRect.top); - memcpy(surface + offset, _fullscreen + offset, height); + int offset = ((_screenWidth - dirtyRect.left - 1) * _screenHeight + dirtyRect.top); + uint16 *fs = _fullscreen + offset; + surface += offset; + for (int x = dirtyRect.right - dirtyRect.left; x > 0; x--) { + memcpy(surface, fs, height); + surface -= _screenHeight; + fs -= _screenHeight; } } else { int width = (dirtyRect.right - dirtyRect.left) * 2; - for (int y = dirtyRect.top; y < dirtyRect.bottom; y++) { - int offset = y * _screenWidth + dirtyRect.left; - memcpy(surface + offset, _fullscreen + offset, width); + int offset = dirtyRect.top * _screenWidth + dirtyRect.left; + uint16 *fs = _fullscreen + offset; + surface += offset; + for (int y = dirtyRect.bottom - dirtyRect.top; y > 0; y--) { + memcpy(surface, fs, width); + surface += _screenWidth; + fs += _screenWidth; } } } @@ -709,6 +747,7 @@ bool OSystem_IPHONE::pollEvent(Common::Event &event) { iPhone_initSurface(_screenWidth, _screenHeight, false); dirtyFullScreen(); + updateScreen(); } break; @@ -961,3 +1000,4 @@ void iphone_main(int argc, char *argv[]) { } #endif + -- cgit v1.2.3