#include #include #include #include #include #include "generic.h" #include "Image.h" #include "Input.h" #include "Output.h" #include "Main.h" int IMG_SX = 128, IMG_SY = 128, BLOC_SX = 128, BLOC_SY = 128; int do_swap = 0; Uint8 * pixels; CODE_BEGINS Color LookUp(char i) { return Color(i << 4, i << 4, i << 4, 255); } void countdown(int o_x, int o_y, int size, int * counter, int * a_x, int * a_y) { if (*counter) { if (size != 1) { int hs = size >> 1; countdown(o_x, o_y, hs, counter, a_x, a_y); if (!*counter) return; countdown(o_x, o_y + hs, hs, counter, a_x, a_y); if (!*counter) return; countdown(o_x + hs, o_y, hs, counter, a_x, a_y); if (!*counter) return; countdown(o_x + hs, o_y + hs, hs, counter, a_x, a_y); } else { *counter = *counter - 1; *a_x = o_x; *a_y = o_y; } } } void putpixel(int x, int y, Color C) { pixels[(y * IMG_SX * 2 + x) * 3 + 0] = C.R; pixels[(y * IMG_SX * 2 + x) * 3 + 1] = C.G; pixels[(y * IMG_SX * 2 + x) * 3 + 2] = C.B; } void drawhline(int y, Color C) { for (int i = 0; i < (IMG_SX << 1); i++) { putpixel(i, y, C); } } void drawvline(int x, Color C) { for (int i = 0; i < (IMG_SY << 1); i++) { putpixel(x, i, C); } } int transform(int x, int y) { int numero_bloc_x = x / BLOC_SX; int numero_bloc_y = y / BLOC_SY; int numero_bloc = numero_bloc_y * (IMG_SX / BLOC_SX) + numero_bloc_x; if (do_swap) { if ((BLOC_SX == BLOC_SY) || ((BLOC_SX >> 1) == BLOC_SY)) { countdown(0, 0, IMG_SY / BLOC_SY, &numero_bloc, &numero_bloc_x, &numero_bloc_y); numero_bloc = numero_bloc_y * (IMG_SX / BLOC_SX) + numero_bloc_x; } } int bx = x % BLOC_SX; int by = y % BLOC_SY; return numero_bloc * BLOC_SX * BLOC_SY + by * BLOC_SX + bx; // return y * IMG_SX + x; } virtual int startup() throw (GeneralException) { int c; if (SDL_Init(SDL_INIT_VIDEO) < 0) { printm(M_ERROR, "Couldn't initialise SDL: %s\n", SDL_GetError()); exit(-1); } atexit(SDL_Quit); SDL_ShowCursor(SDL_DISABLE); while ((c = getopt(argc, argv, "x:y:z:t:")) != EOF) { switch (c) { case 'x': IMG_SX = atoi(optarg); break; case 'y': IMG_SY = atoi(optarg); break; case 'z': BLOC_SX = atoi(optarg); break; case 't': BLOC_SY = atoi(optarg); break; default: printm(M_ERROR, "Unknow option: %c\n", c); throw Exit(-1); } } if ((argc - optind) != 2) { printm(M_ERROR, "Need two arguments\n"); throw Exit(-1); } Input * map = new Input(argv[optind]); Output * tga = new Output(argv[optind + 1]); Image * img = new Image(IMG_SX, IMG_SY); char * buffer = (char *) malloc(IMG_SX * IMG_SY); Byte b; for (int i = 0; i < ((IMG_SX * IMG_SY) >> 1); i++) { int j = i << 1; map->read(&b, 1); buffer[j] = b & 0x0f; buffer[j + 1] = (b & 0xf0) >> 4; } SDL_Surface * screen = 0; screen = SDL_SetVideoMode(IMG_SX * 2, IMG_SY * 2, 24, SDL_HWSURFACE | SDL_DOUBLEBUF); if (!screen) { printm(M_ERROR, "Couldn't get framebuffer\n"); exit(-1); } pixels = ((Uint8 *) screen->pixels); SDL_Event event; bool exitting = false; while (!exitting) { for (int y = 0; y < IMG_SY; y++) { for (int x = 0; x < IMG_SX; x++) { Color c = LookUp(buffer[transform(x, y)]); pixels[((y * 2 + 0) * IMG_SX * 2 + (x * 2 + 0)) * 3 + 0] = c.R; pixels[((y * 2 + 0) * IMG_SX * 2 + (x * 2 + 0)) * 3 + 1] = c.G; pixels[((y * 2 + 0) * IMG_SX * 2 + (x * 2 + 0)) * 3 + 2] = c.B; pixels[((y * 2 + 0) * IMG_SX * 2 + (x * 2 + 1)) * 3 + 0] = c.R; pixels[((y * 2 + 0) * IMG_SX * 2 + (x * 2 + 1)) * 3 + 1] = c.G; pixels[((y * 2 + 0) * IMG_SX * 2 + (x * 2 + 1)) * 3 + 2] = c.B; pixels[((y * 2 + 1) * IMG_SX * 2 + (x * 2 + 0)) * 3 + 0] = c.R; pixels[((y * 2 + 1) * IMG_SX * 2 + (x * 2 + 0)) * 3 + 1] = c.G; pixels[((y * 2 + 1) * IMG_SX * 2 + (x * 2 + 0)) * 3 + 2] = c.B; pixels[((y * 2 + 1) * IMG_SX * 2 + (x * 2 + 1)) * 3 + 0] = c.R; pixels[((y * 2 + 1) * IMG_SX * 2 + (x * 2 + 1)) * 3 + 1] = c.G; pixels[((y * 2 + 1) * IMG_SX * 2 + (x * 2 + 1)) * 3 + 2] = c.B; } } for (int x = 0; x < IMG_SX; x += BLOC_SX) { drawvline(x << 1, Color(255, 255, 0)); } for (int y = 0; y < IMG_SY; y += BLOC_SY) { drawhline(y << 1, Color(255, 255, 0)); } SDL_Flip(screen); SDL_WaitEvent(&event); switch (event.type) { case SDL_KEYDOWN: switch (event.key.keysym.sym) { case SDLK_UP: BLOC_SY >>= 1; break; case SDLK_DOWN: BLOC_SY <<= 1; break; case SDLK_LEFT: BLOC_SX >>= 1; break; case SDLK_RIGHT: BLOC_SX <<= 1; break; case SDLK_SPACE: do_swap ^= 1; break; default: break; } if (BLOC_SX == 0) BLOC_SX = 1; if (BLOC_SY == 0) BLOC_SY = 1; if (BLOC_SX > IMG_SX) BLOC_SX = IMG_SX; if (BLOC_SY > IMG_SY) BLOC_SY = IMG_SY; printm(M_BARE, "Bloc size = %3ix%3i\n", BLOC_SX, BLOC_SY); break; case SDL_QUIT: exitting = true; break; } } img->Fill(); for (int y = 0; y < IMG_SX; y++) { for (int x = 0; x < IMG_SY; x++) { img->SetPixel(x, y, LookUp(buffer[transform(x, y)])); } } img->Prepare(FORMAT_TGA_BASIC); copy(img, tga); SDL_Quit(); return 0; } CODE_ENDS