0 Members and 3 Guests are viewing this topic.
Yeah, now it works. It's much slower than before, though.
Have you made a conditional branch/jump or something smarter ?Remember that using an if inside a setPixel is most likely time cretical. You may want to use faster designs like function pointers.
if(has_colors) setPixel(x,y,color,buffer);
*BUMP*Could one of you help make this faster? What exactly should I do instead of my if statement?
Quote from: Spenceboy98 on August 29, 2013, 06:42:41 am*BUMP*Could one of you help make this faster? What exactly should I do instead of my if statement?Without the last source updated source code ? Does anything has changed since the last one ?
#include <os.h>#include "utils.c"#include "graphics3.c"#include "math.h"#include "nCOMMON.h"#include "touchpad.c"#define R5G6B5(r,g,b) (is_cx ? (((r) << 11) | ((g) << 5) | (b)) : ((int)( 0.229 * (r) + 0.587 * ((g) / 2) + 0.114 * (b)) / 2))int nRC_enableRelativePaths(char **argv){ char buf[256], *p; strcpy(buf, argv[0]); p = strrchr(buf, '/'); if (!p) return -1; *p = '\0'; return NU_Set_Current_Dir(buf) ? -1 : 0;}uint16_t* nRC_loadBMP(char *path){ int size, offset, i, x, bpp, r, g, b; uint16_t *returnValue, color; FILE *temp = fopen(path, "rb"); if(!temp) { printf("Could not open %s\n", path); return NULL; } // Check if the file's 2 first char are BM (indicates bitmap) if(!(fgetc(temp) == 0x42 && fgetc(temp) == 0x4d)) { printf("Image is not a bitmap\n"); fclose(temp); return NULL; } // Check the bits-per-pixel format of the bitmap and converts color accordingly fseek(temp, 0x1c, SEEK_SET); bpp = fgetc(temp); // Gets the 4-bytes numbers of bytes representing pixels, situated at 0x22 // Note that a same size can represent a different number of pixels, depending on bpp fseek(temp, 0x22, SEEK_SET); size = fgetc(temp) | (fgetc(temp) << 8) | (fgetc(temp) << 16) | (fgetc(temp) << 24); // Gets the 4-bytes offset to the start of the pixel table, situated at 0x0a fseek(temp, 0x0a, SEEK_SET); offset = fgetc(temp) | (fgetc(temp) << 8) | (fgetc(temp) << 16) | (fgetc(temp) << 24); fseek(temp, offset, SEEK_SET); switch(bpp) { // Monochrome bitmaps have 1 bit per pixel : 0 is full black, 1 is full white case 1: returnValue = malloc(size * 8 * sizeof(int)); if(!returnValue) { printf("Could not allocate memory"); fclose(temp); return NULL; } for(i = size - 1; i >= 0; i--) { color = fgetc(temp); for(x = 0; x < 8; x++) { returnValue[i * 8 + x] = (color & (1 << x)) ? (is_cx ? 65535 : 15) : 0; } } break; // 16-colours bitmaps have 4 bits per pixel, corresponding to a grayscale. // Fortunately, the non-CX screen uses the same pixel format. case 4: returnValue = malloc(size * 2 * sizeof(int)); if(!returnValue) { printf("Could not allocate memory"); fclose(temp); return NULL; } for(i = size - 1; i >= 0; i--) { x = fgetc(temp); color = x & 0x0f; returnValue[i * 2] = is_cx ? ((color * 2) << 11) | ((color * 4) << 5) | (color * 2) : color; color = (x >> 4) & 0x0f; returnValue[i * 2 + 1] = is_cx ? ((color * 2) << 11) | ((color * 4) << 5) | (color * 2) : color; } break; // 256-colours bitmaps have 8 bits per pixel, corresponding to an index in a palette. // So we must add the 8-bit value to the start of the palette to get the 32-bits colour of the pixel. case 8: printf("Paletted bitmaps not supported\n"); fclose(temp); return NULL; break; // 65536-colours bitmaps have 16 bits per pixel, corresponding to the R5G6B5 colour format. // Fortunately, the CX screen uses the same pixel format. case 16: size >>= 1; returnValue = malloc(size * sizeof(int)); if(!returnValue) { printf("Could not allocate memory\n"); fclose(temp); return NULL; } for(i = size - 1; i >= 0; i--) { color = (uint16_t)(fgetc(temp) | (fgetc(temp) << 8)); returnValue[i] = (is_cx ? color : ((int)( 0.229 * (color >> 11) + 0.587 * ((color >> 6) & 0x1f) + 0.114 * (color & 0x1f)) >> 1)); } break; // 16777216-colours bitmaps have 24 bits per pixel, being 8 bits for red, 8 for green and 8 for blue. // Unfortunately, no TI-Nspire screen supports this format for now, so we have to scale it down to R5G6B5 // even if this means that we loose some quality. case 24: size /= 3; returnValue = malloc(size * sizeof(int)); if(!returnValue) { printf("Could not allocate memory"); fclose(temp); return NULL; } for(i = size - 1; i >= 0; i--) { b = fgetc(temp); g = fgetc(temp); r = fgetc(temp); returnValue[i] = R5G6B5((int)(r / 8), (int)(g / 4), (int)(b / 8)); } break; // This format is the same than the previous one, except that it includes an alpha byte to determine the transparence // degree of the pixel. I never planned to support transparency anyway. case 32: printf("32-bits bitmaps not supported\n"); fclose(temp); return NULL; break; default: printf("Format not supported\n"); fclose(temp); return NULL; break; } fclose(temp); return returnValue;}#define texWidth 64#define texHeight 64#define screenWidth 240#define screenHeight 240int w = 240, h = 240, x, y;uint16_t *texture;int distanceTable[screenWidth][screenHeight];int angleTable[screenWidth][screenHeight];int buffer[screenWidth][screenHeight];void sprite1(void *buffer, int *data, int x, int y, int width, int height){ int i, j; for(i = 0; i < height; i++){ for(j = 0; j < width; j++){ if(x+j < 320 && x+j > 0 && y+i < 240 && y+i > 0){ if(has_colors) setPixel(x+j, y+i, data[i*width+j], buffer); else setPixelBuf(buffer, x+j, y+i, data[i*width+j]); } } }}uint16_t RGBColor(uint8_t r, uint8_t g, uint8_t b){ return ((r / 8) << 11) | ((g / 4) << 5) | (b / 8);}uint16_t HSLtoRGB(int h, float s, float l) { float r = 0.0f; float g = 0.0f; float b = 0.0f; float c = (1-fabs(2*l-1))*s; float tc = c*(1-abs(h%2-1)); switch(h/60) { case 0: r = c; g = tc; break; case 1: g = c; r = tc; break; case 2: g = c; b = tc; break; case 3: b = c; g = tc; break; case 4: b = c; r = tc; break; case 5: r = c; b = tc; break; default: break; } float m = l-c/2; r += m; g += m; b += m; return (uint16_t)(((int)(r*32)<<11)|((int)(g*64)<<5)|((int)(b*32)));}int main(int argc, char *argv[]) { char *screen; screen = (char*)malloc(SCREEN_BYTES_SIZE * sizeof(char)); // just a buffer if(!screen) { exit(0); } if(nRC_enableRelativePaths(argv)) { printf("Couldn't change directory\n"); exit(0); } texture = nRC_loadBMP("texture.bmp.tns"); if(!texture){ free(screen); exit(0); } initTP(); if(!has_colors) lcd_ingray(); for(x = 0; x < w; x++) for(y = 0; y < h; y++) { int angle, distance; float ratio = 32.0; distance = (int)(ratio * texHeight / sqrt((x - w / 2.0) * (x - w / 2.0) + (y - h / 2.0) * (y - h / 2.0))) % texHeight; angle = (0.5 * texWidth * atan2(y - h / 2.0, x - w / 2.0) / M_PI); distanceTable[x][y] = distance; angleTable[x][y] = angle; } float animation = 0; int shiftY = (unsigned int)(texHeight * 0.25); if(has_colors) clearScreen(RGBColor(255,255,255), screen); else clearBuf(screen); //begin the loop while(!isKeyPressed(KEY_NSPIRE_ESC)) { animation = animation+0.04; readTP(); int TZ = getTouchedZone4(); //calculate the shift values out of the animation value int shiftX = (unsigned int)(texWidth * 1.0 * animation); if(isKeyPressed(KEY_NSPIRE_RIGHT) || TZ==6) shiftY++; if(isKeyPressed(KEY_NSPIRE_LEFT) || TZ==4) shiftY--; for(x = 0; x < w; x++) for(y = 0; y < h; y++) { //get the texel from the texture by using the tables, shifted with the animation values int color = texture[((unsigned int)(angleTable[x][y] + shiftY) % texHeight)*texWidth+((unsigned int)(distanceTable[x][y] + shiftX) % texWidth)]; buffer[x][y] = color; } sprite1(screen, buffer[0], 40, 0, 240, 240); switch(has_colors){ case 1: display(screen); //clearScreen(RGBColor(255,255,255), screen); break; case 0: refresh(screen); clearBuf(screen); break; default: refresh(screen); clearBuf(screen); break; } } free(screen); endTP(); return 0;}
#include "utils.c" #include "graphics3.c" #include "math.h" #include "nCOMMON.h" #include "touchpad.c"
void sprite1(void *buffer, int *data, int x, int y, int width, int height){ int i, j; for(i = 0; i < height; i++){ for(j = 0; j < width; j++){ if(x+j < 320 && x+j > 0 && y+i < 240 && y+i > 0){ if(has_colors) setPixel(x+j, y+i, data[i*width+j], buffer); else setPixelBuf(buffer, x+j, y+i, data[i*width+j]); } } }}
void sprite1(void *buffer, int *data, int x, int y, int width, int height){ int i, j; switch (has_colors) { case 1: for(i = 0; i < height; i++){ for(j = 0; j < width; j++){ if(x+j < 320 && x+j > 0 && y+i < 240 && y+i > 0) setPixel(x+j, y+i, data[i*width+j], buffer); } } break; default: for(i = 0; i < height; i++){ for(j = 0; j < width; j++){ if(x+j < 320 && x+j > 0 && y+i < 240 && y+i > 0) setPixelBuf(buffer, x+j, y+i, data[i*width+j]); } } }}
void sprite1(void *buffer, int *data, int x, int y, int width, int height){ if(x > SCREEN_WIDTH || y > SCREEN_HEIGHT || x+w < 0 || y+h < 0) return; if(x < 0) { w += x; x = 0; } if(y < 0) { h += y; y = 0; } if(x + w > SCREEN_WIDTH) w = SCREEN_WIDTH - x; if(y + h > SCREEN_HEIGHT) h = SCREEN_HEIGHT - y; if(w <= 0 || h <= 0) return; int i, j; switch (has_colors) { case 1: for(i = 0; i < height; i++){ for(j = 0; j < width; j++) setPixel(x+j, y+i, data[i*width+j], buffer); } break; default: for(i = 0; i < height; i++){ for(j = 0; j < width; j++) setPixelBuf(buffer, x+j, y+i, data[i*width+j]); } }}
Does anyone have an idea for how to add another texture(so there's two)?