HextileMessage.cpp 7.71 KB
Newer Older
daFischer's avatar
first  
daFischer committed
1 2
/* 
 * File:   HextileMessage.cpp
3
 * Author: Johannes Fischer
daFischer's avatar
first  
daFischer committed
4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
 * 
 * Created on May 22, 2014, 7:08 PM
 */

#include "HextileMessage.h"

uint HextileMessage::hextile_bg, HextileMessage::hextile_fg;
ColorConverter HextileMessage::con;

HextileMessage::HextileMessage(int timestamp, Inflater* in, int size) {
    this->timestamp=timestamp;
    in->readShort(&x);
    in->readShort(&y);
    in->readShort(&w);
    in->readShort(&h);
    data=new SizedArray(size-8);
    in->readSizedArray(data);
    
    hextile_bg=0;
    hextile_fg=0;
}

HextileMessage::~HextileMessage() {
    delete data;
}

30 31 32 33
bool HextileMessage::completeScreen(int w, int h){
    return (this->w==w && this->h==h);
}

daFischer's avatar
first  
daFischer committed
34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
void HextileMessage::paint(SDL_Surface *screen, ProtocolPreferences* prefs)
{
    offSet=0;
    
    //printf("%s%d\n",test.c_str(), data->length);
    
    // scan hextiles
    for (int ty = y; ty < y + h; ty += 16) {
        int th = 16;
        if (y + h - ty < 16)
            th = y + h - ty;

        for (int tx = x; tx < x + w; tx += 16) {
            int tw = 16;
            if (x + w - tx < 16)
                tw = x + w - tx;
            //printf("{%d,%d}\n",tx,ty);
            handleHextileSubrect(screen, prefs, tx, ty, tw, th);
        }
    }
    //printf("(%d,%d)(%d,%d)\n",x,y,w,h);
    //printf("%d\n",data->length-offSet);
56
    SDL_UpdateRect(screen, x,y,w,h);
daFischer's avatar
first  
daFischer committed
57 58
}

59 60 61 62 63 64 65 66 67 68
/**
 * This method has been copied from the Java TTT-Player and adjusted to C++
 * It draws a subrectangle to the screen at (tx,ty)
 * @param screen
 * @param prefs
 * @param tx
 * @param ty
 * @param tw
 * @param th
 */
daFischer's avatar
first  
daFischer committed
69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85
void HextileMessage::handleHextileSubrect(SDL_Surface *screen, ProtocolPreferences* prefs, int tx, int ty, int tw, int th)
{
    unsigned char subencoding;
    read((char*)&subencoding,1);
    //printf("test2 %d\n", subencoding);
    /*// buffering      TODO:
    if (os != null)
        os.writeByte(subencoding);*/
    
    // Is it a raw-encoded sub-rectangle?
    if ((subencoding & HextileRaw) != 0) {
        //printf(".");
        handleRawRect(screen, prefs, tx, ty, tw, th);
        return;
    }
    //printf("|");
    // Read and draw the background if specified.
86
    //ColorConverter con;
daFischer's avatar
first  
daFischer committed
87
    
88
    unsigned char cbuf[ProtocolPreferences::bytesPerPixel];
daFischer's avatar
first  
daFischer committed
89 90

    if ((subencoding & HextileBackgroundSpecified) != 0) {
91
        read((char*)cbuf,ProtocolPreferences::bytesPerPixel);
daFischer's avatar
first  
daFischer committed
92 93 94 95 96 97

        /*// buffering
        if (os != null)
            os.write(cbuf);*/

        // store encoded background color
98
        hextile_bg=con.decodeColor(cbuf, ProtocolPreferences::bytesPerPixel, ProtocolPreferences::format);
daFischer's avatar
first  
daFischer committed
99 100 101 102 103 104 105 106
    }
    //printf("test4\n");
    
    SDL_Rect rect = {tx, ty, tw, th};
    SDL_FillRect(screen, &rect, hextile_bg);

    // Read the foreground color if specified.
    if ((subencoding & HextileForegroundSpecified) != 0) {
107
        read((char*)cbuf,ProtocolPreferences::bytesPerPixel);
daFischer's avatar
first  
daFischer committed
108 109 110 111 112 113

        /*// buffering          TODO:
        if (os != null)
            os.write(cbuf);*/

        // store encoded foreground color
114
        hextile_fg=con.decodeColor(cbuf, ProtocolPreferences::bytesPerPixel, ProtocolPreferences::format);
daFischer's avatar
first  
daFischer committed
115 116 117 118 119 120 121 122 123 124 125 126
    }

    // Done with this tile if there is no sub-rectangles.
    if ((subencoding & HextileAnySubrects) == 0)
        return;

    unsigned int nSubrects = 0;
    read((char*)(&nSubrects), 1);
    int bufsize = nSubrects * 2;
    //printf("%d,",nSubrects);

    if ((subencoding & HextileSubrectsColoured) != 0) {
127
        bufsize += nSubrects * ProtocolPreferences::bytesPerPixel;
daFischer's avatar
first  
daFischer committed
128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144
    }
    //printf("test6 %d<%d\n", nSubrects, bufsize);
    unsigned char buf[bufsize];
    read((char*)buf,bufsize);

    /*// buffering      TODO:
    if (os != null) {
        os.writeByte(nSubrects);
        os.write(buf);
    }*/

    int b1, b2, sx, sy, sw, sh;
    int i = 0;
    
    for (int j = 0; j < nSubrects; j++) {
        if ((subencoding & HextileSubrectsColoured) != 0) {
            // store encoded foreground color
145
            hextile_fg=con.decodeColor(&buf[i], ProtocolPreferences::bytesPerPixel, ProtocolPreferences::format);
daFischer's avatar
first  
daFischer committed
146

147
            i += ProtocolPreferences::bytesPerPixel;
daFischer's avatar
first  
daFischer committed
148 149 150 151 152 153 154 155 156 157 158 159 160 161
        }
        // decode subrect
        b1 = buf[i++] & 0xFF;
        b2 = buf[i++] & 0xFF;
        sx = tx + (b1 >> 4);
        sy = ty + (b1 & 0xf);
        sw = (b2 >> 4) + 1;
        sh = (b2 & 0xf) + 1;

        SDL_Rect rect = {sx, sy, sw, sh};
        SDL_FillRect(screen, &rect, hextile_fg);
    }
}

162 163 164 165 166 167 168 169 170 171
/**
 * This method has been copied from the Java TTT-Player and adjusted to C++
 * It draws raw Pixels to the screen
 * @param screen
 * @param prefs
 * @param tx
 * @param ty
 * @param tw
 * @param th
 */
daFischer's avatar
first  
daFischer committed
172 173 174 175
void HextileMessage::handleRawRect(SDL_Surface *screen, ProtocolPreferences* prefs, int tx, int ty, int tw, int th)
{
    SDL_Rect rect = {0, 0, 1, 1};
    
176
    switch (ProtocolPreferences::bytesPerPixel) {
daFischer's avatar
first  
daFischer committed
177 178
        case 1:
        {
179
            printf("TODO: test bytesPerPixel = 1\n");
180
            for (int dy = ty; dy < ty + th; dy++) {
181 182
                //is.readFully(graphicsContext.pixels8, dy * graphicsContext.ProtocolPreferences::framebufferWidth + x, w);
                read((char*)(screen->pixels)+dy * ProtocolPreferences::framebufferWidth + tx,tw);
daFischer's avatar
first  
daFischer committed
183 184 185

                /*// buffering          TODO:?
                if (os != null)
186
                    os.write(graphicsContext.pixels8, dy * graphicsContext.ProtocolPreferences::framebufferWidth + x, w);*/
daFischer's avatar
first  
daFischer committed
187 188 189 190 191
            }
            break;
        }
        case 2:
        {
192
            unsigned char rawColor[ProtocolPreferences::bytesPerPixel];
daFischer's avatar
first  
daFischer committed
193
            uint color;
194
            if (ProtocolPreferences::bigEndian)
daFischer's avatar
first  
daFischer committed
195 196 197 198
                for (int dy = ty; dy < ty + th; dy++)
                {
                    for(int dx = 0; dx < tw; dx++)
                    {
199 200
                        read((char*)rawColor, ProtocolPreferences::bytesPerPixel);
                        color = con.decodeColor(rawColor,ProtocolPreferences::bytesPerPixel,ProtocolPreferences::format);
daFischer's avatar
first  
daFischer committed
201 202 203 204 205 206 207 208 209 210
                        rect.x = dx + tx;
                        rect.y = dy;
                        SDL_FillRect(screen, &rect, color);
                    }
                }
            else
                for (int dy = ty; dy < ty + th; dy++)
                {
                    for(int dx = 0; dx < tw; dx++)
                    {
211 212
                        read((char*)rawColor, ProtocolPreferences::bytesPerPixel);
                        color = con.decodeColor(rawColor,ProtocolPreferences::bytesPerPixel,ProtocolPreferences::format);
daFischer's avatar
first  
daFischer committed
213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229
                        rect.x = dx + tx;
                        rect.y = dy;
                        SDL_FillRect(screen, &rect, color);
                    }
                }
            break;
        }
        default:
        {
            /*char buf[w * 4];
            for (int dy = y; dy < y + h; dy++) {
                read(buf,w*4);

                /*//* buffering
                if (os != null)
                    os.write(buf);*//*

230 231
                int offset = dy * ProtocolPreferences::framebufferWidth + x;
                if (ProtocolPreferences::bigEndian)
daFischer's avatar
first  
daFischer committed
232 233 234 235 236 237 238 239 240 241 242
                    for (int i = 0; i < w; i++)
                        (int*)(screen->pixels)[offset + i] = (buf[i * 4 + 1] & 0xFF) << 16 | (buf[i * 4 + 2] & 0xFF) << 8 | (buf[i * 4 + 3] & 0xFF);
                else
                    for (int i = 0; i < w; i++)
                        (int*)(screen->pixels)[offset + i] = (buf[i * 4 + 2] & 0xFF) << 16 | (buf[i * 4 + 1] & 0xFF) << 8 | (buf[i * 4] & 0xFF);
            }*/
            break;
        }
    }
}

243
int HextileMessage::getArea() {
daFischer's avatar
first  
daFischer committed
244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259
    return w*h;
}

bool HextileMessage::read(char* dest, int n){
    for(int i = 0; i < n; i++)
    {
        if(offSet>=data->length)
        {
            //printf("failed\n");
            return false;
        }
        dest[i]=data->array[offSet];
        offSet++;
    }
    return true;
}