From c0f33240cb9d376ad068a5818f619ae8c358c740 Mon Sep 17 00:00:00 2001 From: Adam Greenwood-Byrne Date: Mon, 15 Mar 2021 22:04:22 +0000 Subject: [PATCH] Added loadspr.c with examples/wgt29.c which exercises it - a scrolly thing --- part12-wgt/Makefile | 7 ++- part12-wgt/bin/letters.spr | Bin 0 -> 12160 bytes part12-wgt/examples/wgt29.c | 110 ++++++++++++++++++++++++++++++++++++ part12-wgt/loadspr.c | 90 +++++++++++++++++++++++++++++ part12-wgt/wgt.c | 23 ++++++++ part12-wgt/wgt.h | 5 ++ part12-wgt/wscreen.c | 66 ++++++++++++++++++++++ 7 files changed, 299 insertions(+), 2 deletions(-) create mode 100644 part12-wgt/bin/letters.spr create mode 100644 part12-wgt/examples/wgt29.c create mode 100644 part12-wgt/loadspr.c diff --git a/part12-wgt/Makefile b/part12-wgt/Makefile index 251e5f7..6633d38 100644 --- a/part12-wgt/Makefile +++ b/part12-wgt/Makefile @@ -17,11 +17,14 @@ bin/wgt1blk.o: bin/wgt1.blk bin/wgt2blk.o: bin/wgt2.blk $(LLVMPATH)/llvm-objcopy -I binary -O elf64-littleaarch64 -B aarch64 $< $@ +bin/lettersspr.o: bin/letters.spr + $(LLVMPATH)/llvm-objcopy -I binary -O elf64-littleaarch64 -B aarch64 $< $@ + %.o: %.c $(LLVMPATH)/clang --target=aarch64-elf $(CLANGFLAGS) -c $< -o $@ -kernel8.img: boot/boot.o $(OFILES) bin/wgt1pal.o bin/wgt1blk.o bin/wgt2blk.o - $(LLVMPATH)/ld.lld -m aarch64elf -nostdlib boot/boot.o $(OFILES) bin/wgt1pal.o bin/wgt1blk.o bin/wgt2blk.o -T boot/link.ld -o kernel8.elf +kernel8.img: boot/boot.o $(OFILES) bin/wgt1pal.o bin/wgt1blk.o bin/wgt2blk.o bin/lettersspr.o + $(LLVMPATH)/ld.lld -m aarch64elf -nostdlib boot/boot.o $(OFILES) bin/wgt1pal.o bin/wgt1blk.o bin/wgt2blk.o bin/lettersspr.o -T boot/link.ld -o kernel8.elf $(LLVMPATH)/llvm-objcopy -O binary kernel8.elf kernel8.img clean: diff --git a/part12-wgt/bin/letters.spr b/part12-wgt/bin/letters.spr new file mode 100644 index 0000000000000000000000000000000000000000..19d8402fadd14aa3086ae57d24dab92581476d5b GIT binary patch literal 12160 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 F{{XtyrAPn( literal 0 HcmV?d00001 diff --git a/part12-wgt/examples/wgt29.c b/part12-wgt/examples/wgt29.c new file mode 100644 index 0000000..8664f11 --- /dev/null +++ b/part12-wgt/examples/wgt29.c @@ -0,0 +1,110 @@ +#include "wgt.h" +#include "include/mem.h" + +// ######## REQUIRED FUNCTIONS ######## + +unsigned long state0 = 1000; +unsigned long state1 = 2000; + +unsigned long rand(void) +{ + unsigned long s1 = state0; + unsigned long s0 = state1; + + state0 = s0; + s1 ^= s1 << 23; + s1 ^= s1 >> 17; + s1 ^= s0; + s1 ^= s0 >> 26; + state1 = s1; + + return state0 + state1; +} + +void wait_msec(unsigned int n) +{ + register unsigned long f, t, r; + + // Get the current counter frequency + asm volatile ("mrs %0, cntfrq_el0" : "=r"(f)); + // Read the current counter + asm volatile ("mrs %0, cntpct_el0" : "=r"(t)); + // Calculate expire value for counter + t+=((f/1000)*n)/1000; + do{asm volatile ("mrs %0, cntpct_el0" : "=r"(r));}while(r 4, maxsprite contains + the number of the highest sprite in the file. (empty sprites at + the end are not kept in the file. */ + if (a <= 3) + startingsprite = 1; + else + startingsprite = 0; + + memcpy_char(&buf, file, 13); + file += 13; + + if (0 == memcmp (" Sprite File ", &buf[0], 13)) + /* see if it is a sprite file */ + { + for (int k=0;k<256;k++) { + pal[k].r = 4 * *file++; + pal[k].g = 4 * *file++; + pal[k].b = 4 * *file++; + } + wsetpalette (0, 255, pal); + + maxsprite = (short)*file; /* maximum sprites in this file */ + file += 2; + + for (i = start; i <= end; i++) /* make all sprites null + (still need to call wfreesprites) */ + image_array[i] = NULL; + + for (i = startingsprite; i <= maxsprite; i++) /* load them in */ + { + spritemade = (unsigned int)*file; /* flag to see if sprite exists */ + file += 2; + if (spritemade == 1) + { + a = (unsigned int)*file; /* get width and height */ + file += 2; + b = (unsigned int)*file; + file += 2; + + if ((i >= start) && (i <= end)) /* Load this one */ + { + size = a * b; + + image_array[i] = (block)malloc ((size * 4) + 12); + block arr = image_array[i]; + + *arr++ = a; + *arr++ = b; + + for (int k=0;k 0) + { + if (*s1++ != *s2++) + return s1[-1] < s2[-1] ? -1 : 1; + } + + return 0; +} + int abs(int i) { return i < 0 ? -i : i; diff --git a/part12-wgt/wgt.h b/part12-wgt/wgt.h index 3271f7e..a89ba1d 100644 --- a/part12-wgt/wgt.h +++ b/part12-wgt/wgt.h @@ -56,6 +56,8 @@ extern short bx,by,tx,ty; void *memset(void *dest, unsigned int val, unsigned len); void *memcpy(void *dest, const void *src, unsigned len); void *memcpy_xray(void *dest, const void *src, unsigned len); +void *memcpy_char(void *dest, const void *src, unsigned len); +int memcmp(char *str1, char *str2, unsigned count); int abs(int i); int strlen(const char *str); @@ -118,3 +120,6 @@ void wnormscreen (void); void wvertres (short x, short y, short y2, block image); void wwipe (short x, short y, short x2, short y2, block image); void wskew (short x, short y, block image, short degrees); +short wloadsprites (color *pal, unsigned char *file, block *image_array, short start, short end); +void wfreesprites (block *image_array, short start, short end); +void wcopyscreen (short x, short y, short x2, short y2, block source, short destx, short desty, block dest); diff --git a/part12-wgt/wscreen.c b/part12-wgt/wscreen.c index 11faa78..02a3b9f 100644 --- a/part12-wgt/wscreen.c +++ b/part12-wgt/wscreen.c @@ -1,5 +1,7 @@ #include "wgt.h" +#define fastcopy memcpy + void wsetscreen (block image) { if (image == NULL) @@ -31,3 +33,67 @@ void wnormscreen (void) bx = WGT_SYS.xres - 1; by = WGT_SYS.yres - 1; } + +void wcopyscreen (short x, short y, short x2, short y2, block source, short destx, short desty, block dest) +{ + unsigned int swidth, dwidth; + short width, height, display; + short ctr; /* Y line counter */ + + if (source == NULL) + { + source = abuf; /* Set to visual screen */ + swidth = 320; + } + else { + swidth = *source; + source += 2; /* Skip over width and height */ + } + + width = abs (x - x2) + 1; /* Width of each row to copy */ + height = abs (y - y2) + 1; /* Height of area to copy */ + + if (destx + width > bx) + display = bx + 1 - destx; + else display = width; /* Clip width */ + + if (height > (by + 1 - desty)) + height = (by + 1 - desty); + + source += x + (y * swidth); /* Clip height */ + if (desty < ty) + { + source += (ty - desty) * swidth; + height -= ty - desty; + desty = ty; + } /* clip y */ + + if (destx < tx) + { + source += tx - destx; + display -= tx - destx; + destx = tx; + } /* clip x */ + + if (dest == NULL) + { + dest = abuf; /* Set to visual screen */ + dwidth = 320; + } + else + { + dwidth = *dest; + dest += 2; + } + + /* Skip over width & height in image data */ + dest += destx + (desty * dwidth); /* Find row offset in image data */ + + if ((height > 0) && (display > 0)) + for (ctr = y; ctr < y + height; ctr++) + { + fastcopy (dest, source, display); /* Copy DISPLAY bytes to dest */ + source += swidth; /* Advance one row */ + dest += dwidth; + } +}