Exemplo n.º 1
0
 private function _loadLBM($file)
 {
     $lbm = fopen($file, "rb");
     if (!$lbm) {
         return false;
     }
     fseek($lbm, 0, SEEK_END);
     $size = ftell($lbm);
     fseek($lbm, 0, SEEK_SET);
     $form = file_helpers::freadstring($lbm, 4, false);
     if ($form != "FORM") {
         return $this->_error("not a LBM file");
     }
     $length = file_helpers::freadint($lbm);
     $pbm = file_helpers::freadstring($lbm, 4, false);
     if ($pbm != "PBM ") {
         return $this->_error("not a LBM file with PBM structure");
     }
     while (!feof($lbm) && ftell($lbm) < $size) {
         $chunk = file_helpers::freadstring($lbm, 4, false);
         // Länge einlesen
         $length = file_helpers::freadbint($lbm);
         #echo $chunk." = ".$length."<br>\n";
         // Bei ungerader Zahl aufrunden
         if ($length & 1) {
             ++$length;
         }
         switch ($chunk) {
             case "BMHD":
                 // Breite & Höhe einlesen
                 $this->image['header']['width'] = file_helpers::freadbshort($lbm);
                 $this->image['header']['height'] = file_helpers::freadbshort($lbm);
                 // Unbekannte Daten ( 4 Byte ) berspringen
                 fseek($lbm, 4, SEEK_CUR);
                 // Farbtiefe einlesen
                 $this->image['header']['depth'] = file_helpers::freadshort($lbm);
                 // Nur 256 Farben und nicht mehr!
                 if ($this->image['header']['depth'] != 8) {
                     $this->_error("Invalid File: LBM with 8bit colors are supported only");
                     return false;
                 }
                 // Kompressionflag lesen
                 $this->image['header']['compression'] = file_helpers::freadshort($lbm);
                 if ($this->image['header']['compression'] != 1) {
                     $this->_error("Invalid File: LBM has unknown compression flag: " . $this->image['header']['compression']);
                     return false;
                 }
                 $length -= 12;
                 // Rest überspringen
                 fseek($lbm, $length, SEEK_CUR);
                 break;
             case "BODY":
                 switch ($this->image['header']['compression']) {
                     case 0:
                         // uncompressed
                         return false;
                     case 1:
                         $pos = 0;
                         // Solange einlesen, bis Block zuende bzw. Datei zuende ist
                         while ($length >= 0 && !feof($lbm) && ftell($lbm) < $size) {
                             // Typ lesen
                             $ctype = file_helpers::freadchar($lbm);
                             --$length;
                             if ($length == 0) {
                                 continue;
                             }
                             if ($ctype < 128) {
                                 for ($i = 0; $i <= $ctype; ++$i) {
                                     $this->image['body'][$pos] = file_helpers::freadchar($lbm);
                                     --$length;
                                     ++$pos;
                                 }
                             } else {
                                 $count = 0xff - $ctype + 1;
                                 $color = file_helpers::freadchar($lbm);
                                 --$length;
                                 for ($i = 0; $i <= $count; ++$i) {
                                     $this->image['body'][$pos] = $color;
                                     ++$pos;
                                 }
                             }
                         }
                         if ($pos < $this->image['header']['width'] * $this->image['header']['height']) {
                             $this->_error("ooops? {$pos} " . $this->image['header']['width'] * $this->image['header']['height']);
                             return false;
                         }
                         break;
                 }
                 break;
             case "CMAP":
                 if ($length != 256 * 3) {
                     $this->_error("Invalid Chunk: {$chunk} with length {$length} does not have 256 rgb values");
                     return false;
                 }
                 $this->palette->set_256rgb(s2pal::read_256rgb($lbm));
                 break;
             case "DPPS":
                 // known but unused
             // known but unused
             case "CRNG":
             case "TINY":
                 fseek($lbm, $length, SEEK_CUR);
                 break;
             default:
                 $this->_error("Unknown Chunk: {$chunk} with length {$length}");
                 // Rest überspringen
                 fseek($lbm, $length, SEEK_CUR);
                 break;
         }
     }
     fclose($lbm);
     return true;
 }
Exemplo n.º 2
0
 private function _generate()
 {
     $files = array(0 => array("PAL5.BBM", "GOU5.DAT", "TEX5.LBM"), 1 => array("PAL6.BBM", "GOU6.DAT", "TEX6.LBM"), 2 => array("PAL7.BBM", "GOU7.DAT", "TEX7.LBM"));
     if (!$this->_load()) {
         return $this->error("failed to load map");
     }
     $s2pal = new s2pal(__DIR__ . "/S2/GFX/PALETTE/" . $files[$this->header['type']][0]);
     $s2gou = new s2gou(__DIR__ . "/S2/DATA/TEXTURES/" . $files[$this->header['type']][1]);
     $s2lbm = new s2lbm(__DIR__ . "/S2/GFX/TEXTURES/" . $files[$this->header['type']][2]);
     $size = 12;
     //6;
     $img = imagecreatetruecolor($this->header['width'] * $size, $this->header['height'] * $size);
     imagecolortransparent($img, $s2pal->apply($img, $s2pal->transparent()));
     for ($x = 0; $x < $this->header['width']; $x++) {
         for ($y = 0; $y < $this->header['height']; $y++) {
             $color = 0xfe;
             $landscape_obj = $this->blocks['objects'][$y * $this->header['width'] + $x];
             // wald?
             if ($landscape_obj >= 0xc4 && $landscape_obj <= 0xc6) {
                 $color = $landscape_obj - 0x9b;
             } else {
                 $terrain2 = $this->blocks['terrain2'][$y * $this->header['width'] + $x];
                 if ($terrain2 > 0x40) {
                     // hafen?
                     $terrain2 -= 0x40;
                 }
                 $cx = -1;
                 $cy = -1;
                 $color = array();
                 switch ($terrain2) {
                     // first row
                     case 2:
                         $cx = 16;
                         $cy = 0;
                         break;
                     case 4:
                     case 7:
                         $cx = 64;
                         $cy = 0;
                         break;
                     case 3:
                         $cx = 112;
                         $cy = 0;
                         break;
                     case 15:
                         $cx = 160;
                         $cy = 0;
                         break;
                         // 2nd row
                     // 2nd row
                     case 1:
                         $cx = 16;
                         $cy = 48;
                         break;
                     case 11:
                         $cx = 64;
                         $cy = 48;
                         break;
                     case 12:
                         $cx = 112;
                         $cy = 48;
                         break;
                     case 13:
                         $cx = 160;
                         $cy = 48;
                         break;
                         // 3rd row
                     // 3rd row
                     case 0:
                         $cx = 16;
                         $cy = 96;
                         break;
                     case 8:
                         $cx = 64;
                         $cy = 96;
                         break;
                     case 9:
                         $cx = 112;
                         $cy = 96;
                         break;
                     case 10:
                         $cx = 160;
                         $cy = 96;
                         break;
                         // 4th row
                     // 4th row
                     case 14:
                         $color = array(236, 167, 233);
                         break;
                     case 18:
                         $cx = 64;
                         $cy = 144;
                         break;
                     case 16:
                         $color = array(57, 248, 248);
                         break;
                         // water
                     // water
                     case 5:
                         $color = array(61, 42, 240);
                         break;
                     case 6:
                         $color = array(61, 42, 240);
                         break;
                     case 19:
                         $color = array(61, 42, 240);
                         break;
                         // single pixel texture
                     // single pixel texture
                     case 17:
                         $cx = 0;
                         $cy = 254;
                         break;
                         // unknown bottom 3
                     // unknown bottom 3
                     case 20:
                         $color = array(57, 248, 248);
                         break;
                     case 21:
                         $color = array(57, 248, 248);
                         break;
                     case 22:
                         $color = array(57, 248, 248);
                         break;
                 }
                 if ($cx != -1 && $cy != -1) {
                     $color = $s2lbm->color($cx, $cy);
                     //trigger_error("($cx, $cy) => $color");
                 } else {
                     // hardcoded
                     $color = $color[$this->header['type']];
                 }
             }
             $shadow = 0x40;
             if ($terrain2 != 0x5 && $terrain2 != 0x10) {
                 $shadow = $this->blocks['shadow'][$y * $this->header['width'] + $x];
             }
             $color = $s2pal->apply($img, $s2gou->apply($s2pal, $color, $shadow));
             imagefilledrectangle($img, $x * $size, $y * $size, $x * $size + $size, $y * $size + $size, $color);
         }
     }
     $text = $this->header['name'] . " von " . $this->header['author'];
     $text .= "\n";
     $text .= "(" . $this->header['width'] . "x" . $this->header['height'] . ", " . $this->header['players'] . " players)";
     $size = 12;
     $box = imagettfbbox($size, 0, __DIR__ . "/s2map.ttf", $text);
     imagefilledrectangle($img, 2, 2, 6 + $box[2], 8 + $size * 1.45 * 2, imagecolorallocate($img, 0xff, 0xff, 0xff));
     imagettftext($img, $size, 0, 4, 18, imagecolorallocate($img, 0x0, 0x0, 0x0), __DIR__ . "/s2map.ttf", $text);
     $temp_file = tempnam(sys_get_temp_dir(), 's2map');
     // create image file
     imagepng($img, $temp_file);
     imagedestroy($img);
     $img = fopen($temp_file, "rb");
     $img_data = fread($img, filesize($temp_file));
     fclose($img);
     unlink($temp_file);
     $map = fopen($this->file, "rb");
     $map_data = fread($map, filesize($this->file));
     fclose($map);
     $last_changed = filemtime($this->file);
     if (!$this->sql->query_exec("REPLACE INTO `s2map` (`hash`, `name`, `author`, `players`, `type`, `width`, `height`, `map`, `preview`, `last_changed`)\n\t\t                            VALUES (\n\t\t                                '" . $this->sql->escape($this->hash) . "',\n\t\t                                '" . $this->sql->escape($this->header['name']) . "',\n\t\t                                '" . $this->sql->escape($this->header['author']) . "',\n\t\t                                '" . $this->sql->escape($this->header['players']) . "',\n\t\t                                '" . $this->sql->escape($this->header['type']) . "',\n\t\t                                '" . $this->sql->escape($this->header['width']) . "',\n\t\t                                '" . $this->sql->escape($this->header['height']) . "',\n\t\t                                '" . $this->sql->escape($map_data) . "',\n\t\t                                '" . $this->sql->escape($img_data) . "',\n\t\t                                '" . $this->sql->escape($last_changed) . "')")) {
         return 0;
     }
     return $this->sql->query_one("SELECT preview FROM `s2map` WHERE `hash` = '" . $this->sql->escape($this->hash) . "'");
 }