Full Screen Rotation and Scaling ================================ The Algorithm ------------- This isn't really anything exciting, but it's a very simple aproach to full screen image rotation and scaling. Simple and slow. The algorithm used is just a simple reverse transformation. Basically what I do is run from the upper left hand corner of the DESTINATION buffer, figure out which pixel to pull from the source image, and put it there. Nothing to it. The way I find out where to grab the pixel from is like this: x' = cos(x)-sin(y); y' = sin(x)+cos(y); To scale the image I simply multiply the x' and y' by the scaleRatio. The Speed -- Lack of? --------------------- Ok, so speed isn't really a good word to use here. But if I were to use floating point it would be a heck of a lot slower than it is now. The ways I sped this thing up was by using lookup tables and fixed point math. The tables I made are: long sinTab[256]; // sin table -- 256 degrees in a circle, not 360 :) long cosTab[256]; // cosin table int yTab[200]; // Y offset table. So I don't have to multiply the // y value by 320. Very minor speed increase. long scaleTab[128]; // Starting at 0, the largest, and ending at 127 // the smallest. 63 is the original size. This // table is just something I made to increase the // speed of scaling. You can adjust it to be as // big as you want. sinTab, cosTab, and scaleTab are all fixed point numbers. I calculate them by taking the floating point number and multiplying it by 1024. When I put them to use I simply shift them to the right 10 places, which in effect, divides by 1024, but is much faster. I suppose you could use greater precision if you wanted, but for this program it's not necessary. sinTab/cosTab: int i; for (i=0; i<256; i++) { cosTab[i] = cos((6.28/256)*i)*1024; sinTab[i] = sin((6.28/256)*i)*1024; } What we're doing here is looping from 0 to 255 and calculating the (co)sin for each value. We use radians because that's what Borland C++ 3.1's math functions provide us with. By dividing 6.28 by 256 we make it possible to make a complete circle with only 256 "degrees." We then multiply the (co)sin by 1024 and assign it to a long. This is what makes our fixed point number. When we use these values in the future we will divide our RESULT by 1024. Ie: These are both correct: (5*cosTab[14])/1024; or (5*cosTab[14])>>10; This is not: 5*(cosTab[14]/1024) or 5*(cosTab[14]>>10); Here's why: If you divide cosTab[14] by 1024 before multiplying it then you lose your precision thus making fixed point numbers pretty much useless. But if you multiply the number by 5, then devide by 1024 you will get a precise number. Now that we've gotten that down we can move on to the next part. scaleTab: int i; float scale; scale = 1.0/64.0; for (i=0; i<128; i++) { scaleTab[i] = scale*1024; scale += 1.0/64.0; } Ok, this is something that I made up and is definately not the only (or the best) way to do this. All this is, is a table of scaling factors with the biggest starting at index 0, the smallest at 127, an the original size at 63. I'm not really gonna explain this too much because it's really pretty dumb. But it does the trick. If you want to make your own scaling factors it shouldn't be too difficult to figure out. You could easily remove the code for scaling from "fullrot.c" by replacing: xT = ((((x*c)>>10)-ys)*scaleTab[scale])>>10; yT = ((((x*s)>>10)+yc)*scaleTab[scale])>>10; with: xT = ((x*c)>>10)-ys; yT = ((x*s)>>10)+yc; You'll actually get a small speed increase by doing this too. I personally suggest playing around with it until you understand it. It's very simple. Compiling --------- To compile this program you may have to modify the Makefile that I've included to locate your include/lib directories properly. You must have Borland C++ 3.1 or greater and TASM 3.1 or greater. I use the -B option which will allow bcc to compile to an ASM file then call TASM 3.1 to assemble it. The reason I do this is because bcc doesn't understand 386 specific assembly instructions which I use for the screen blit. Beyond that there should be no difficulties. I'm sorry to all you Watcom 9.5, Symantech, or MS C folks out there but there's not a whole lot I can do since I don't own anything other than BC++ 3.1. Credits ------- - The palette manipulation code in "gfxpal.c" was originally written by Mark Morley. I've made quite a few alterations to it to fit my needs, but it was originally done by Mark. It was pulled from the VGL library that he created. You can find VGL20.ZIP at suncad.camosun.bc.ca in /pub/morley. - The pcx loader was originally written by Christopher Lampton, author of "Flights of Fantasy", published by Waite Group Press. The ISBN for "Flights of Fantasy" is 1-878739-18-2. Me, Myself, and I ----------------- I am Scott Deming. A starving programmer looking for a career in game dev. So far I haven't had much luck, but I suppose you can't expect things to be given to you on a silver platter now can you? :) Anyways, I can be reached via any of the following: Internet: sad@umcc.umich.edu CIS: 73053,3347 Snail: 14985 Brookview Dr., Apt #201. Riverview, MI 48192 If this documentation (if you can call it that) doesn't explain things very well, then feel free to drop me email. I will try to answer any questions I get. If my response isn't instant then I apologize, but I will respond. ============================================================================= This source code is Copyright 1994, by Scott A. Deming. All Rights Reserved! Permission is granted to anyone who wishes to use it as a learning tool, for profit, or not-for profit. I don't care how you use it, but I would like to know about anyone it helps. Please drop me a line one way or another. It's always nice to hear from people who have actually gotten something out of what I've written. ============================================================================= Last modified: 3-15-94 Enjoy! P.S. A little note about "test.pcx" This is a logo that I created for a company that I am a partner (one of two) of. Currently we have nothing published because we have nothing finished. Someday maybe we will. Someday maybe we won't. If there is anyone out there looking for artwork for their games, or programming please drop me a line. I'm desperatly seeking work. My other partner is a very good artist, and I'm an ok programmer. Thanks for listening. Scott A. Deming sad@umcc.umich.edu