all repos — mgba @ 9e10c8f1c264642191de6082c0d8f1f7cef02540

mGBA Game Boy Advance Emulator

Util: Add missing files
Jeffrey Pfau jeffrey@endrift.com
Sun, 28 Aug 2016 23:01:39 -0700
commit

9e10c8f1c264642191de6082c0d8f1f7cef02540

parent

56722324efdf8d5c9675f7658a35b0d05e9f8594

2 files changed, 164 insertions(+), 0 deletions(-)

jump to
A src/util/patch-fast.c

@@ -0,0 +1,130 @@

+/* Copyright (c) 2013-2016 Jeffrey Pfau + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#include "patch-fast.h" + +DEFINE_VECTOR(PatchFastExtents, struct PatchFastExtent); + +size_t _fastOutputSize(struct Patch* patch, size_t inSize); +bool _fastApplyPatch(struct Patch* patch, const void* in, size_t inSize, void* out, size_t outSize); + +void initPatchFast(struct PatchFast* patch) { + PatchFastExtentsInit(&patch->extents, 32); + patch->d.outputSize = _fastOutputSize; + patch->d.applyPatch = _fastApplyPatch; +} + +void deinitPatchFast(struct PatchFast* patch) { + PatchFastExtentsDeinit(&patch->extents); +} + +bool diffPatchFast(struct PatchFast* patch, const void* restrict in, const void* restrict out, size_t size) { + PatchFastExtentsClear(&patch->extents); + const uint32_t* iptr = in; + const uint32_t* optr = out; + size_t extentOff = 0; + struct PatchFastExtent* extent = NULL; + size_t off; + for (off = 0; off < (size & ~15); off += 16) { + uint32_t a = iptr[0] ^ optr[0]; + uint32_t b = iptr[1] ^ optr[1]; + uint32_t c = iptr[2] ^ optr[2]; + uint32_t d = iptr[3] ^ optr[3]; + iptr += 4; + optr += 4; + if (a | b | c | d) { + if (!extent) { + extent = PatchFastExtentsAppend(&patch->extents); + extent->offset = off; + extentOff = 0; + } + extent->extent[extentOff] = a; + extent->extent[extentOff + 1] = b; + extent->extent[extentOff + 2] = c; + extent->extent[extentOff + 3] = d; + extentOff += 4; + if (extentOff == PATCH_FAST_EXTENT) { + extent->length = extentOff * 4; + extent = NULL; + } + } else if (extent) { + extent->length = extentOff * 4; + extent = NULL; + } + } + if (extent) { + extent->length = extentOff * 4; + extent = NULL; + } + const uint32_t* iptr8 = iptr; + const uint32_t* optr8 = optr; + for (; off < size; ++off) { + uint8_t a = iptr8[0] ^ optr8[0]; + ++iptr8; + ++optr8; + if (a) { + if (!extent) { + extent = PatchFastExtentsAppend(&patch->extents); + extent->offset = off; + } + ((uint8_t*) extent->extent)[extentOff] = a; + ++extentOff; + } else if (extent) { + extent->length = extentOff; + extent = NULL; + } + } + if (extent) { + extent->length = extentOff; + extent = NULL; + } + + return true; +} + +size_t _fastOutputSize(struct Patch* patch, size_t inSize) { + UNUSED(patch); + return inSize; +} + +bool _fastApplyPatch(struct Patch* p, const void* in, size_t inSize, void* out, size_t outSize) { + struct PatchFast* patch = (struct PatchFast*) p; + if (inSize != outSize) { + return false; + } + const uint32_t* iptr = in; + uint32_t* optr = out; + size_t lastWritten = 0; + size_t s; + for (s = 0; s < PatchFastExtentsSize(&patch->extents); ++s) { + struct PatchFastExtent* extent = PatchFastExtentsGetPointer(&patch->extents, s); + if (extent->length + extent->offset > outSize) { + return false; + } + memcpy(optr, iptr, extent->offset - lastWritten); + optr = (uint32_t*) out + extent->offset / 4; + iptr = (uint32_t*) in + extent->offset / 4; + uint32_t* eptr = extent->extent; + size_t off; + for (off = 0; off < (extent->length & ~15); off += 16) { + optr[0] = iptr[0] ^ eptr[0]; + optr[1] = iptr[1] ^ eptr[1]; + optr[2] = iptr[2] ^ eptr[2]; + optr[3] = iptr[3] ^ eptr[3]; + optr += 4; + iptr += 4; + eptr += 4; + } + for (; off < extent->length; ++off) { + *(uint8_t*) optr = *(uint8_t*) iptr ^ *(uint8_t*) eptr; + ++optr; + ++iptr; + ++eptr; + } + lastWritten = extent->offset + off; + } + memcpy(optr, iptr, outSize - lastWritten); + return true; +}
A src/util/patch-fast.h

@@ -0,0 +1,34 @@

+/* Copyright (c) 2013-2016 Jeffrey Pfau + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#ifndef PATCH_FAST_H +#define PATCH_FAST_H + +#include "util/common.h" + +#include "util/patch.h" +#include "util/vector.h" + +#define PATCH_FAST_EXTENT 256 + +struct PatchFastExtent { + size_t length; + size_t offset; + uint32_t extent[PATCH_FAST_EXTENT]; +}; + +DECLARE_VECTOR(PatchFastExtents, struct PatchFastExtent); + +struct PatchFast { + struct Patch d; + + struct PatchFastExtents extents; +}; + +void initPatchFast(struct PatchFast*); +void deinitPatchFast(struct PatchFast*); +bool diffPatchFast(struct PatchFast* patch, const void* restrict in, const void* restrict out, size_t size); + +#endif