diff options
-rw-r--r-- | default.nix | 3 | ||||
-rw-r--r-- | scale.diff | 241 |
2 files changed, 243 insertions, 1 deletions
diff --git a/default.nix b/default.nix index df27166..ec733b2 100644 --- a/default.nix +++ b/default.nix @@ -1,5 +1,6 @@ { pkgs ? import <nixpkgs> { }, ... }: pkgs.oneko.overrideAttrs (oldAttrs: rec { - src = ./src; + #src = ./src; + patches = [ ./scale.diff ]; }) diff --git a/scale.diff b/scale.diff new file mode 100644 index 0000000..e16248c --- /dev/null +++ b/scale.diff @@ -0,0 +1,241 @@ +diff --git a/oneko.c b/oneko.c +index d2b81fe..d66cf55 100644 +--- a/oneko.c ++++ b/oneko.c +@@ -68,6 +68,7 @@ char *Foreground = NULL; /* foreground */ + char *Background = NULL; /* background */ + long IntervalTime = 0L; /* time */ + double NekoSpeed = (double)0; /* speed */ ++int ScaleFactor = NOTDEFINED; + int IdleSpace = 0; /* idle */ + int NekoMoyou = NOTDEFINED; /* tora */ + int NoShape = NOTDEFINED; /* noshape */ +@@ -268,6 +269,52 @@ Animation AnimationPattern[][2] = + + static void NullFunction(); + ++/* ++ * Scales the bitmap. ++ */ ++ ++char* ++ScaleBitmap(char* inputBitmap) ++{ ++ int scaledBitmapWidth = BITMAP_WIDTH * ScaleFactor; ++ int scaledBitmapHeight = BITMAP_HEIGHT * ScaleFactor; ++ int scaledBitmapSize = (scaledBitmapWidth / 8) * scaledBitmapHeight; ++ char* result = malloc(scaledBitmapSize); ++ ++ for (int i = 0; i < scaledBitmapSize; i++) { ++ result[i] = 0x00; ++ } ++ ++ for (int srcY = 0; srcY < BITMAP_HEIGHT; srcY++) { ++ for (int srcX = 0; srcX < BITMAP_WIDTH; srcX++) { ++ int srcByteOffset = (srcX / 8) + (srcY * BITMAP_WIDTH / 8); ++ int srcBitOffset = (srcX % 8); ++ char bit = inputBitmap[srcByteOffset] >> srcBitOffset & 0x01; ++ ++ if (bit != 0) { ++ for (int ySub = 0; ySub < ScaleFactor; ySub++) { ++ int dstY = srcY * ScaleFactor + ySub; ++ ++ for (int xSub = 0; xSub < ScaleFactor; xSub += 8) { ++ int dstX = srcX * ScaleFactor + xSub; ++ int dstByteOffset = (dstX / 8) + (dstY * scaledBitmapWidth / 8); ++ int dstBitCount = ScaleFactor - xSub; ++ if (dstBitCount > 8) { ++ dstBitCount = 8; ++ } ++ int dstBitOffset = (dstX % 8); ++ char dstBitMask = ((1 << dstBitCount) - 1) << dstBitOffset; ++ ++ result[dstByteOffset] |= dstBitMask; ++ } ++ } ++ } ++ } ++ } ++ ++ return result; ++} ++ + /* + * $@%S%C%H%^%C%W%G!<%?!&(JGC $@=i4|2=(J + */ +@@ -289,20 +336,28 @@ InitBitmapAndGCs() + BitmapGCDataTablePtr->GCCreatePtr != NULL; + BitmapGCDataTablePtr++) { + ++ char* scaledPixelPattern = ScaleBitmap(BitmapGCDataTablePtr->PixelPattern[NekoMoyou]); ++ + *(BitmapGCDataTablePtr->BitmapCreatePtr) + = XCreatePixmapFromBitmapData(theDisplay, theRoot, +- BitmapGCDataTablePtr->PixelPattern[NekoMoyou], +- BITMAP_WIDTH, BITMAP_HEIGHT, ++ scaledPixelPattern, ++ BITMAP_WIDTH * ScaleFactor, BITMAP_HEIGHT * ScaleFactor, + theForegroundColor.pixel, + theBackgroundColor.pixel, + DefaultDepth(theDisplay, theScreen)); + ++ free(scaledPixelPattern); ++ + theGCValues.tile = *(BitmapGCDataTablePtr->BitmapCreatePtr); + ++ char* scaledMaskPattern = ScaleBitmap(BitmapGCDataTablePtr->MaskPattern[NekoMoyou]); ++ + *(BitmapGCDataTablePtr->BitmapMasksPtr) + = XCreateBitmapFromData(theDisplay, theRoot, +- BitmapGCDataTablePtr->MaskPattern[NekoMoyou], +- BITMAP_WIDTH, BITMAP_HEIGHT); ++ scaledMaskPattern, ++ BITMAP_WIDTH * ScaleFactor, BITMAP_HEIGHT * ScaleFactor); ++ ++ free(scaledMaskPattern); + + *(BitmapGCDataTablePtr->GCCreatePtr) + = XCreateGC(theDisplay, theWindow, +@@ -368,6 +423,14 @@ GetResources() + } + } + ++ if (ScaleFactor == NOTDEFINED) { ++ if ((resource = NekoGetDefault("scale")) != NULL) { ++ if (num = atoi(resource)) { ++ ScaleFactor = num; ++ } ++ } ++ } ++ + if (IdleSpace == 0) { + if ((resource = NekoGetDefault("idle")) != NULL) { + if (num = atoi(resource)) { +@@ -408,6 +471,9 @@ GetResources() + if (IntervalTime == 0) { + IntervalTime = AnimalDefaultsDataTable[NekoMoyou].time; + } ++ if (ScaleFactor == NOTDEFINED) { ++ ScaleFactor = 1; ++ } + if (NekoSpeed == (double)0) { + NekoSpeed = (double)(AnimalDefaultsDataTable[NekoMoyou].speed); + } +@@ -690,7 +756,7 @@ InitScreen(DisplayName) + CWOverrideRedirect; + + theWindow = XCreateWindow(theDisplay, theRoot, 0, 0, +- BITMAP_WIDTH, BITMAP_HEIGHT, ++ BITMAP_WIDTH * ScaleFactor, BITMAP_HEIGHT * ScaleFactor, + 0, theDepth, InputOutput, CopyFromParent, + theWindowMask, &theWindowAttributes); + +@@ -815,7 +881,7 @@ DrawNeko(x, y, DrawAnime) + DontMapped = 0; + } + XFillRectangle(theDisplay, theWindow, DrawGC, +- 0, 0, BITMAP_WIDTH, BITMAP_HEIGHT); ++ 0, 0, BITMAP_WIDTH * ScaleFactor, BITMAP_HEIGHT * ScaleFactor); + } + + XFlush(theDisplay); +@@ -835,7 +901,7 @@ void + RedrawNeko() + { + XFillRectangle(theDisplay, theWindow, NekoLastGC, +- 0, 0, BITMAP_WIDTH, BITMAP_HEIGHT); ++ 0, 0, BITMAP_WIDTH * ScaleFactor, BITMAP_HEIGHT * ScaleFactor); + + XFlush(theDisplay); + } +@@ -915,15 +981,15 @@ IsWindowOver() + if (NekoY <= 0) { + NekoY = 0; + ReturnValue = True; +- } else if (NekoY >= WindowHeight - BITMAP_HEIGHT) { +- NekoY = WindowHeight - BITMAP_HEIGHT; ++ } else if (NekoY >= WindowHeight - BITMAP_HEIGHT * ScaleFactor) { ++ NekoY = WindowHeight - BITMAP_HEIGHT * ScaleFactor; + ReturnValue = True; + } + if (NekoX <= 0) { + NekoX = 0; + ReturnValue = True; +- } else if (NekoX >= WindowWidth - BITMAP_WIDTH) { +- NekoX = WindowWidth - BITMAP_WIDTH; ++ } else if (NekoX >= WindowWidth - BITMAP_WIDTH * ScaleFactor) { ++ NekoX = WindowWidth - BITMAP_WIDTH * ScaleFactor; + ReturnValue = True; + } + +@@ -1048,24 +1114,24 @@ CalcDxDy() + LargeX = (double)(MouseX - NekoX - BITMAP_WIDTH / 2); + + LargeY = (double)(theTargetAttributes.y +- + YOffset - NekoY - BITMAP_HEIGHT); ++ + YOffset - NekoY - BITMAP_HEIGHT * ScaleFactor); + } + else { + MouseX = theTargetAttributes.x + + theTargetAttributes.width / 2 + XOffset; + MouseY = theTargetAttributes.y + YOffset; +- LargeX = (double)(MouseX - NekoX - BITMAP_WIDTH / 2); +- LargeY = (double)(MouseY - NekoY - BITMAP_HEIGHT); ++ LargeX = (double)(MouseX - NekoX - BITMAP_WIDTH * ScaleFactor / 2); ++ LargeY = (double)(MouseY - NekoY - BITMAP_HEIGHT * ScaleFactor); + } + } + else { +- LargeX = (double)(MouseX - NekoX - BITMAP_WIDTH / 2); +- LargeY = (double)(MouseY - NekoY - BITMAP_HEIGHT); ++ LargeX = (double)(MouseX - NekoX - BITMAP_WIDTH * ScaleFactor / 2); ++ LargeY = (double)(MouseY - NekoY - BITMAP_HEIGHT * ScaleFactor); + } + } + else { +- LargeX = (double)(MouseX - NekoX - BITMAP_WIDTH / 2); +- LargeY = (double)(MouseY - NekoY - BITMAP_HEIGHT); ++ LargeX = (double)(MouseX - NekoX - BITMAP_WIDTH * ScaleFactor / 2); ++ LargeY = (double)(MouseY - NekoY - BITMAP_HEIGHT * ScaleFactor); + } + + DoubleLength = LargeX * LargeX + LargeY * LargeY; +@@ -1120,9 +1186,9 @@ NekoThinkDraw() + } else if ((NekoMoveDy < 0 && NekoY <= 0) + || (ToFocus && theTarget != None && NekoY > MouseY)){ + SetNekoState(NEKO_U_TOGI); +- } else if ((NekoMoveDy > 0 && NekoY >= WindowHeight - BITMAP_HEIGHT) ++ } else if ((NekoMoveDy > 0 && NekoY >= WindowHeight - BITMAP_HEIGHT * ScaleFactor) + || (ToFocus && theTarget != None +- && NekoY < MouseY - BITMAP_HEIGHT)){ ++ && NekoY < MouseY - BITMAP_HEIGHT * ScaleFactor)){ + SetNekoState(NEKO_D_TOGI); + } else { + SetNekoState(NEKO_JARE); +@@ -1298,8 +1364,8 @@ ProcessNeko() + + /* $@G-$N=i4|2=(J */ + +- NekoX = (WindowWidth - BITMAP_WIDTH / 2) / 2; +- NekoY = (WindowHeight - BITMAP_HEIGHT / 2) / 2; ++ NekoX = (WindowWidth - BITMAP_WIDTH * ScaleFactor / 2) / 2; ++ NekoY = (WindowHeight - BITMAP_HEIGHT * ScaleFactor / 2) / 2; + + NekoLastX = NekoX; + NekoLastY = NekoY; +@@ -1438,6 +1504,15 @@ GetArguments(argc, argv, theDisplayName) + exit(1); + } + } ++ else if (strcmp(argv[ArgCounter], "-scale") == 0) { ++ ArgCounter++; ++ if (ArgCounter < argc) { ++ ScaleFactor = atoi(argv[ArgCounter]); ++ } else { ++ fprintf(stderr, "%s: -scale option error.\n", ProgramName); ++ exit(1); ++ } ++ } + else if (strcmp(argv[ArgCounter], "-time") == 0) { + ArgCounter++; + if (ArgCounter < argc) { |