Source

BASIC-RoBots / src / display.py

##
## display.py for BASIC-RoBots
##
## Copyright (C) 2012 Pierre Surply
## <pierre.surply@gmail.com>
##
## This file is part of BASIC-RoBots.
##
##    BASIC-RoBots is free software: you can redistribute it and/or modify
##    it under the terms of the GNU General Public License as published by
##    the Free Software Foundation, either version 3 of the License, or
##    (at your option) any later version.
##
##    BASIC-RoBots is distributed in the hope that it will be useful,
##    but WITHOUT ANY WARRANTY; without even the implied warranty of
##    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
##    GNU General Public License for more details.
##
##    You should have received a copy of the GNU General Public License
##    along with BASIC-RoBots.  If not, see <http://www.gnu.org/licenses/>. 
## 
## Started on  Wed May  9 17:19:46 2012 Pierre Surply
## Last update Wed Sep  5 13:51:30 2012 Pierre Surply
##

import pygame
from pygame.locals import *

from OpenGL.GL import *
from OpenGL.GLU import *

import surface

show_fps = False

class Display:
    def __init__(self):
        pygame.init()
        pygame.display.set_caption("BASIC-RoBots")
        self.set_display((640, 480))

        glEnable(GL_TEXTURE_2D)
        glEnable (GL_BLEND);
        glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

        self.set_tile()
        self.set_display_list()
        self.ascii = pygame.image.load("res/img/font.png").convert_alpha()
        self.ascii_wb = surface.cut_surface(self.ascii, (8, 12))
        self.ascii_bw = surface.cut_surface(surface.change_color(self.ascii, \
                                                                     pygame.Color(0, 0, 0, 255),\
                                                                     pygame.Color(255, 255, 255, 255)),\
                                                (8, 12))
        self.ascii_gg = surface.cut_surface(surface.change_color(self.ascii, \
                                                                     pygame.Color(0, 255, 0, 255)),\
                                                (8, 12))
        self.ascii_g = surface.cut_surface(surface.change_color(self.ascii, \
                                                                     pygame.Color(0, 100, 0, 255)),\
                                               (8, 12))
        self.ascii_b = surface.cut_surface(surface.change_color(self.ascii, \
                                                                    pygame.Color(0, 100, 200, 255)),\
                                               (8, 12))
        self.ascii_r = surface.cut_surface(surface.change_color(self.ascii, \
                                                                    pygame.Color(100, 0, 0, 255)),\
                                               (8, 12))
        self.ascii_rr = surface.cut_surface(surface.change_color(self.ascii, \
                                                                     pygame.Color(255, 0, 0, 255)),\
                                               (8, 12))
        self.ascii_rb = surface.cut_surface(surface.change_color(self.ascii, \
                                                                     pygame.Color(200, 00, 0, 255),\
                                                                     pygame.Color(255, 255, 255, 255)),\
                                               (8, 12))
        self.ascii_gb = surface.cut_surface(surface.change_color(self.ascii, \
                                                                     pygame.Color(0, 100, 0, 255),\
                                                                     pygame.Color(255, 255, 255, 255)),\
                                               (8, 12))
        self.last_ticks = pygame.time.get_ticks()
        self.frame = 0

    def set_display_list(self):
        self.list_char = glGenLists(1)
        glNewList(self.list_char,GL_COMPILE)
        glBegin(GL_QUADS) 
        glColor3d(0xFF, 0xFF, 0xFF)
        glTexCoord2f(0, 0); glVertex2f(0, 12)
        glTexCoord2f(0, 1); glVertex2f(0, 0)
        glTexCoord2f(1, 1); glVertex2f(8, 0)
        glTexCoord2f(1, 0); glVertex2f(8, 12)        
        glEnd()
        glEndList()

    def set_display(self, size):
        self.window = pygame.display.set_mode(size, pygame.OPENGL | pygame.DOUBLEBUF | pygame.RESIZABLE)
        glMatrixMode(GL_PROJECTION)
        glLoadIdentity()
        gluOrtho2D(0, self.window.get_width(), self.window.get_height(), 0)

    def set_bg(self):
        self.bg = pygame.Surface(self.window.get_size())
        self.bg.fill(pygame.Color(0, 0, 0))
        self.env = pygame.Surface((self.window.get_width() / 2, self.window.get_height()))

    def set_tile(self):
        self.tile = [[None] * (self.window.get_width() / 8) \
                         for i in range((self.window.get_height() / 12))]

    def set_tile_fullscreen(self):
        self.term_fullscreen = not(self.term_fullscreen)
 
    def render_terminal(self, fullscreen=False):
        glMatrixMode(GL_MODELVIEW)
        glLoadIdentity()

        if fullscreen:
            w = len(self.tile[0])
        else:
            w = len(self.tile[0])/2
        h = len(self.tile)
        glDisable(GL_TEXTURE_2D)
        glBegin(GL_QUADS)
        glColor4ub(0, 0, 0, 0xCC)
        glTexCoord2f(0, 0); glVertex2f(0, h*12)
        glTexCoord2f(0, 1); glVertex2f(0, 0)
        glTexCoord2f(1, 1); glVertex2f(w*8, 0)
        glTexCoord2f(1, 0); glVertex2f(w*8, h*12)
        glEnd()
        glEnable(GL_TEXTURE_2D)
        for y in range(h):
            for x in range(w):
                if self.tile[y][x] != None:
                    glPushMatrix()
                    glTranslated(x*8, y*12, 0)
                    glBindTexture(GL_TEXTURE_2D, self.tile2surface(self.tile[y][x]))
                    glCallList(self.list_char)
                    glPopMatrix()

    def flip(self):
        if show_fps:
            self.frame += 1
            if self.frame >= 100:
                self.frame = 0
                current_ticks = pygame.time.get_ticks()
                pygame.display.set_caption("BASIC-RoBots - " + \
                                               str(100000 / (current_ticks - self.last_ticks)) + " fps")
                self.last_ticks = pygame.time.get_ticks()
        pygame.display.flip()
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)

    def print_char(self, (x, y), tile):
        if len(self.tile) > y and len(self.tile[0]) > x:
            self.tile[y][x] = tile
            return True
        else:
            return False

    def resize(self, size):
        if size[0] >= 80 and size[1] >= 120: 
            self.set_display(size)
            glViewport(0, 0, size[0], size[1])
            self.set_tile()

    def tile2surface(self, tile):
        # MSB
        # 8 bits : id
        #          - 0x00 : Character white on black
        #          - 0x01 : Character black on white
        #          - 0x02 : Green
        #          - 0x03 : Dark green
        #          - 0x04 : Blue
        #          - 0x05 : Dark red
        #          - 0x06 : Red
        #          - 0x07 : Green on white
        #          - 0x08 : Red on white
        # 8 bits : data
        # LSB
        if isinstance(tile, int):
            tile_t = tile >> 8
            data = tile & 0xFF
            if tile_t == 0x00:
                return self.ascii_wb[data]
            elif tile_t == 0x01:
                return self.ascii_bw[data]
            elif tile_t == 0x02:
                return self.ascii_gg[data]
            elif tile_t == 0x03:
                return self.ascii_g[data]
            elif tile_t == 0x04:
                return self.ascii_b[data]
            elif tile_t == 0x05:
                return self.ascii_r[data]
            elif tile_t == 0x06:
                return self.ascii_rr[data]
            elif tile_t == 0x07:
                return self.ascii_gb[data]
            elif tile_t == 0x08:
                return self.ascii_rb[data]
            else:
                return self.ascii_wb[0]
        else:
            return self.ascii_bw[0]

    def draw_frame(self, (x, y, w, h), border):
        for i in range(w):
            self.print_char((x+i, y), border)
        for i in range(w):
            self.print_char((x+i, y+h), border)
        for i in range(h):
            self.print_char((x, y+i), border)
        for i in range(h+1):
            self.print_char((x+w, y+i), border)
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.