From be93315649984c2beae238b6d355888c90d44204 Mon Sep 17 00:00:00 2001 From: dg <dg@51575b47-30f0-44d4-a5cc-537603b46e54> Date: Wed, 9 Dec 2009 00:41:11 +0000 Subject: [PATCH] opengl test git-svn-id: http://svn.net-core.org/repos/t-engine4@107 51575b47-30f0-44d4-a5cc-537603b46e54 --- game/engine/Entity.lua | 4 +- game/engine/Map.lua | 53 ++++++- game/engine/Tiles.lua | 6 +- game/modules/tome/class/Game.lua | 18 ++- .../tome/data/zones/ancient_ruins/zone.lua | 2 +- premake4.lua | 2 +- src/core_lua.c | 144 +++++++++++++++++- src/display_sdl.h | 2 + src/main.c | 93 +++++++++-- src/map.c | 137 +++++++++++++++++ src/map.h | 19 +++ 11 files changed, 449 insertions(+), 31 deletions(-) create mode 100644 src/map.c create mode 100644 src/map.h diff --git a/game/engine/Entity.lua b/game/engine/Entity.lua index 0de153a342..ca58f24206 100644 --- a/game/engine/Entity.lua +++ b/game/engine/Entity.lua @@ -135,9 +135,9 @@ function _M:loadList(...) local e = self.new(t) res[#res+1] = e if t.define_as then res[t.define_as] = e end - print("new entity", t.name) +-- print("new entity", t.name) for k, ee in pairs(e) do - print("prop:", k, ee) +-- print("prop:", k, ee) end end, load = function(f) diff --git a/game/engine/Map.lua b/game/engine/Map.lua index 0c28e506ec..90aad086a9 100644 --- a/game/engine/Map.lua +++ b/game/engine/Map.lua @@ -32,7 +32,7 @@ rememberDisplayOrder = { ACTOR, TERRAIN } function _M:setViewPort(x, y, w, h, tile_w, tile_h, fontname, fontsize) self.display_x, self.display_y = x, y self.viewport = {width=w, height=h, mwidth=math.floor(w/tile_w), mheight=math.floor(h/tile_h)} - self.tiles = Tiles.new(tile_w, tile_h, fontname, fontsize) + self.tiles = Tiles.new(tile_w, tile_h, fontname, fontsize, true) self.tile_w, self.tile_h = tile_w, tile_h end @@ -57,6 +57,7 @@ function _M:init(w, h) self.seens = {} self.remembers = {} self.effects = {} + self._map = core.map.newMap(w, h, self.mx, self.my, self.viewport.mwidth, self.viewport.mheight) for i = 0, w * h - 1 do self.map[i] = {} end self:loaded() @@ -67,6 +68,7 @@ function _M:save() return class.save(self, { _fov_lite = true, _fov = true, + _map = true, surface = true }) end @@ -75,6 +77,7 @@ function _M:loaded() if x < 0 or y < 0 or x >= self.w or y >= self.h then return end if v ~= nil then t[x + y * self.w] = v + self:updateMap(x, y) end return t[x + y * self.w] end @@ -107,7 +110,10 @@ function _M:fov(x, y, d) -- Reset seen grids if self.clean_fov then self.clean_fov = false - for i = 0, self.w * self.h - 1 do self.seens[i] = nil end + for i = 0, self.w - 1 do for j = 0, self.h - 1 do + self.seens(i, j, false) + end end +-- for i = 0, self.w * self.h - 1 do self.seens[i] = nil end end self._fov(x, y, d) end @@ -120,11 +126,32 @@ function _M:fovLite(x, y, d) -- Reset seen grids if self.clean_fov then self.clean_fov = false - for i = 0, self.w * self.h - 1 do self.seens[i] = nil end + for i = 0, self.w - 1 do for j = 0, self.h - 1 do + self.seens(i, j, false) + end end +-- for i = 0, self.w * self.h - 1 do self.seens[i] = nil end self._fov_lite(x, y, d) end end +function _M:updateMap(x, y) + local order = displayOrder + local e, si = nil, 1 + local z = x + y * self.w + + if self.seens[z] or self.remembers[z] then + if not self.seens[z] then order = rememberDisplayOrder end + while not e and si <= #order do e = self(x, y, order[si]) si = si + 1 end + if e then + if self.seens[z] then + self._map:setGrid(x, y, self.tiles:get(e.display, e.color_r, e.color_g, e.color_b, e.color_br, e.color_bg, e.color_bb, e.image)) + elseif self.remembers[z] then + self._map:setGrid(x, y, self.tiles:get(e.display, e.color_r/3, e.color_g/3, e.color_b/3, e.color_br/3, e.color_bg/3, e.color_bb/3, e.image)) + end + end + end +end + --- Sets/gets a value from the map -- It is defined as the function metamethod, so one can simply do: mymap(x, y, Map.TERRAIN) -- @param x position @@ -136,6 +163,8 @@ function _M:call(x, y, pos, entity) if entity then self.map[x + y * self.w][pos] = entity self.changed = true + + self:updateMap(x, y) else if self.map[x + y * self.w] then if not pos then @@ -154,6 +183,7 @@ end function _M:remove(x, y, pos) if self.map[x + y * self.w] then self.map[x + y * self.w][pos] = nil + self:updateMap(x, y) self.changed = true end end @@ -161,13 +191,19 @@ end --- Displays the map on a surface -- @return a surface containing the drawn map function _M:display() + do + self._map:toScreen(self.display_x, self.display_y) + self.changed = false + return + end + -- If nothing changed, return the same surface as before - if not self.changed then return self.surface end +-- if not self.changed then return self.surface end self.changed = false self.clean_fov = true -- Erase and the display the map - self.surface:erase() +-- self.surface:erase() if not self.multi_display then -- Version without multi display local e, si @@ -184,9 +220,9 @@ function _M:display() while not e and si <= #order do e = self(i, j, order[si]) si = si + 1 end if e then if self.seens[z] then - self.surface:merge(self.tiles:get(e.display, e.color_r, e.color_g, e.color_b, e.color_br, e.color_bg, e.color_bb, e.image), (i - self.mx) * self.tile_w, (j - self.my) * self.tile_h) + self.tiles:get(e.display, e.color_r, e.color_g, e.color_b, e.color_br, e.color_bg, e.color_bb, e.image):toScreen((i - self.mx) * self.tile_w, (j - self.my) * self.tile_h) elseif self.remembers[z] then - self.surface:merge(self.tiles:get(e.display, e.color_r/3, e.color_g/3, e.color_b/3, e.color_br/3, e.color_bg/3, e.color_bb/3, e.image), (i - self.mx) * self.tile_w, (j - self.my) * self.tile_h) + self.tiles:get(e.display, e.color_r/3, e.color_g/3, e.color_b/3, e.color_br/3, e.color_bg/3, e.color_bb/3, e.image):toScreen((i - self.mx) * self.tile_w, (j - self.my) * self.tile_h) end -- Tactical overlay ? if self.view_faction and e.faction then @@ -246,6 +282,7 @@ function _M:apply(x, y) if self.lites[x + y * self.w] then self.seens[x + y * self.w] = true self.remembers[x + y * self.w] = true + self:updateMap(x, y) end end @@ -256,6 +293,7 @@ function _M:applyLite(x, y) self.lites[x + y * self.w] = true self.seens[x + y * self.w] = true self.remembers[x + y * self.w] = true + self:updateMap(x, y) end --- Check all entities of the grid for a property @@ -328,6 +366,7 @@ function _M:checkMapViewBounded() if self.my < 0 then self.my = 0 self.changed = true end if self.mx > self.w - self.viewport.mwidth then self.mx = self.w - self.viewport.mwidth self.changed = true end if self.my > self.h - self.viewport.mheight then self.my = self.h - self.viewport.mheight self.changed = true end + self._map:setScroll(self.mx, self.my) end --- Gets the tile under the mouse diff --git a/game/engine/Tiles.lua b/game/engine/Tiles.lua index e0365a7d19..68bff87f9f 100644 --- a/game/engine/Tiles.lua +++ b/game/engine/Tiles.lua @@ -7,7 +7,8 @@ module(..., package.seeall, class.make) prefix = "/data/gfx/" use_images = true -function _M:init(w, h, fontname, fontsize) +function _M:init(w, h, fontname, fontsize, texture) + self.texture = texture self.w, self.h = w, h self.font = core.display.newFont(fontname or "/data/font/VeraMono.ttf", fontsize or 14) self.repo = {} @@ -41,9 +42,12 @@ function _M:get(char, fr, fg, fb, br, bg, bb, image) s:drawString(self.font, char, (self.w - w) / 2, (self.h - h) / 2, fr, fg, fb) end + if self.texture then s = s:glTexture() end + self.repo[char] = self.repo[char] or {} self.repo[char][fgidx] = self.repo[char][fgidx] or {} self.repo[char][fgidx][bgidx] = s + print("caching") return s end end diff --git a/game/modules/tome/class/Game.lua b/game/modules/tome/class/Game.lua index 2d65dcfb2d..419e71094e 100644 --- a/game/modules/tome/class/Game.lua +++ b/game/modules/tome/class/Game.lua @@ -74,7 +74,7 @@ function _M:newGame() self.zone = Zone.new("ancient_ruins") self.player = Player.new{ name=self.player_name, max_life=25, max_mana=25, max_stamina=25, display='@', color_r=230, color_g=230, color_b=230, - unused_stats = 6, unused_talents = 3, + unused_stats = 6, unused_talents = 3, image="player.png", move_others=true, } @@ -144,6 +144,18 @@ function _M:onTurn() end function _M:display() +--[[ + if self.level and self.level.map then + -- Display the map and compute FOV for the player if needed +-- if self.level.map.changed then +-- self.level.map:fov(self.player.x, self.player.y, 20) +-- self.level.map:fovLite(self.player.x, self.player.y, 4) +-- end + self.level.map:display() + --:toScreen(self.level.map.display_x, self.level.map.display_y) + end +-- ]] +-- [[ self.log:display():toScreen(self.log.display_x, self.log.display_y) self.player_display:display():toScreen(self.player_display.display_x, self.player_display.display_y) self.talents_display:display():toScreen(self.talents_display.display_x, self.talents_display.display_y) @@ -154,7 +166,8 @@ function _M:display() self.level.map:fov(self.player.x, self.player.y, 20) self.level.map:fovLite(self.player.x, self.player.y, 4) end - self.level.map:display():toScreen(self.level.map.display_x, self.level.map.display_y) + self.level.map:display() +-- :toScreen(self.level.map.display_x, self.level.map.display_y) -- Display the targetting system if active self.target:display() @@ -179,6 +192,7 @@ function _M:display() end engine.GameTurnBased.display(self) +-- ]] end function _M:targetMode(v, msg, co, typ) diff --git a/game/modules/tome/data/zones/ancient_ruins/zone.lua b/game/modules/tome/data/zones/ancient_ruins/zone.lua index 6635de37d2..971dc8047d 100644 --- a/game/modules/tome/data/zones/ancient_ruins/zone.lua +++ b/game/modules/tome/data/zones/ancient_ruins/zone.lua @@ -2,7 +2,7 @@ return { name = "ancient ruins", level_range = {1, 5}, max_level = 5, - width = 50, height = 50, + width = 100, height = 100, -- all_remembered = true, all_lited = true, -- persistant = true, diff --git a/premake4.lua b/premake4.lua index 15c1665c5b..25bef7ef61 100644 --- a/premake4.lua +++ b/premake4.lua @@ -42,7 +42,7 @@ configuration "macosx" targetdir "." configuration "not macosx" - links { "SDL", "SDL_ttf", "SDL_image", "SDL_gfx", "SDL_mixer" } + links { "SDL", "SDL_ttf", "SDL_image", "SDL_gfx", "SDL_mixer", "GL", "GLU" } configuration "windows" defines { [[TENGINE_HOME_PATH='"T-Engine"']] } diff --git a/src/core_lua.c b/src/core_lua.c index a580048194..98481dcee7 100644 --- a/src/core_lua.c +++ b/src/core_lua.c @@ -9,7 +9,6 @@ #include "physfs.h" #include "SFMT.h" #include "mzip.h" -#include <SDL.h> #include <SDL_ttf.h> /****************************************************************** @@ -390,15 +389,25 @@ static int sdl_new_surface(lua_State *L) SDL_Surface **s = (SDL_Surface**)lua_newuserdata(L, sizeof(SDL_Surface*)); auxiliar_setclass(L, "sdl{surface}", -1); + Uint32 rmask, gmask, bmask, amask; +#if SDL_BYTEORDER == SDL_BIG_ENDIAN + rmask = 0xff000000; + gmask = 0x00ff0000; + bmask = 0x0000ff00; + amask = 0x000000ff; +#else + rmask = 0x000000ff; + gmask = 0x0000ff00; + bmask = 0x00ff0000; + amask = 0xff000000; +#endif + *s = SDL_CreateRGBSurface( - screen->flags, + SDL_SWSURFACE | SDL_SRCALPHA, w, h, - screen->format->BitsPerPixel, - screen->format->Rmask, - screen->format->Gmask, - screen->format->Bmask, - screen->format->Amask + 32, + rmask, gmask, bmask, amask ); return 1; } @@ -453,13 +462,98 @@ static int sdl_surface_toscreen(lua_State *L) SDL_Surface **s = (SDL_Surface**)auxiliar_checkclass(L, "sdl{surface}", 1); int x = luaL_checknumber(L, 2); int y = luaL_checknumber(L, 3); + + /* if (s && *s) { sdlDrawImage(screen, *s, x, y); } + */ + + GLuint t; + glGenTextures(1, &t); + glBindTexture(GL_TEXTURE_2D, t); + + // Paramétrage de la texture. + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + + // get the number of channels in the SDL surface + GLint nOfColors = (*s)->format->BytesPerPixel; + GLenum texture_format; + if (nOfColors == 4) // contains an alpha channel + { + if ((*s)->format->Rmask == 0x000000ff) + texture_format = GL_RGBA; + else + texture_format = GL_BGRA; + } else if (nOfColors == 3) // no alpha channel + { + if ((*s)->format->Rmask == 0x000000ff) + texture_format = GL_RGB; + else + texture_format = GL_BGR; + } else { + printf("warning: the image is not truecolor.. this will probably break %d\n", nOfColors); + // this error should not go unhandled + } + + // Jonction entre OpenGL et SDL. + glTexImage2D(GL_TEXTURE_2D, 0, 3, (*s)->w, (*s)->h, 0, texture_format, GL_UNSIGNED_BYTE, (*s)->pixels); + + glBegin( GL_QUADS ); /* Draw A Quad */ + glTexCoord2f(0,0); glVertex2f(0 + x, 0 + y); + glTexCoord2f(0,1); glVertex2f(0 + x, (*s)->h + y); + glTexCoord2f(1,1); glVertex2f((*s)->w + x, (*s)->h + y); + glTexCoord2f(1,0); glVertex2f((*s)->w + x, 0 + y); + glEnd( ); /* Done Drawing The Quad */ + + glDeleteTextures(1, &t); + return 0; } +static int sdl_surface_to_texture(lua_State *L) +{ + SDL_Surface **s = (SDL_Surface**)auxiliar_checkclass(L, "sdl{surface}", 1); + + GLuint *t = (GLuint*)lua_newuserdata(L, sizeof(GLuint)); + auxiliar_setclass(L, "gl{texture}", -1); + + glGenTextures(1, t); + glBindTexture(GL_TEXTURE_2D, *t); + + // Paramétrage de la texture. + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + + // get the number of channels in the SDL surface + GLint nOfColors = (*s)->format->BytesPerPixel; + GLenum texture_format; + if (nOfColors == 4) // contains an alpha channel + { + if ((*s)->format->Rmask == 0x000000ff) + texture_format = GL_RGBA; + else + texture_format = GL_BGRA; + } else if (nOfColors == 3) // no alpha channel + { + if ((*s)->format->Rmask == 0x000000ff) + texture_format = GL_RGB; + else + texture_format = GL_BGR; + } else { + printf("warning: the image is not truecolor.. this will probably break\n"); + // this error should not go unhandled + } + + // Jonction entre OpenGL et SDL. + glTexImage2D(GL_TEXTURE_2D, 0, nOfColors, (*s)->w, (*s)->h, 0, texture_format, GL_UNSIGNED_BYTE, (*s)->pixels); + return 1; +} + static int sdl_surface_merge(lua_State *L) { SDL_Surface **dst = (SDL_Surface**)auxiliar_checkclass(L, "sdl{surface}", 1); @@ -488,6 +582,32 @@ static int sdl_set_window_title(lua_State *L) return 0; } +static int sdl_free_texture(lua_State *L) +{ + GLuint *t = (GLuint*)auxiliar_checkclass(L, "gl{texture}", 1); + glDeleteTextures(1, t); + lua_pushnumber(L, 1); + return 1; +} + +static int sdl_texture_toscreen(lua_State *L) +{ + GLuint *t = (GLuint*)auxiliar_checkclass(L, "gl{texture}", 1); + int x = luaL_checknumber(L, 2); + int y = luaL_checknumber(L, 3); + + glBindTexture(GL_TEXTURE_2D, *t); + glBegin( GL_QUADS ); /* Draw A Quad */ + glTexCoord2f(0,0); glVertex2f(0 + x, 0 + y); + glTexCoord2f(0,1); glVertex2f(0 + x, 16 + y); + glTexCoord2f(1,1); glVertex2f(16 + x, 16 + y); + glTexCoord2f(1,0); glVertex2f(16 + x, 0 + y); + glEnd( ); /* Done Drawing The Quad */ + + return 0; +} + + static const struct luaL_reg displaylib[] = { {"fullscreen", sdl_fullscreen}, @@ -510,6 +630,15 @@ static const struct luaL_reg sdl_surface_reg[] = {"putChar", lua_display_char}, {"drawString", sdl_surface_drawstring}, {"alpha", sdl_surface_alpha}, + {"glTexture", sdl_surface_to_texture}, + {NULL, NULL}, +}; + +static const struct luaL_reg sdl_texture_reg[] = +{ + {"__gc", sdl_free_texture}, + {"close", sdl_free_texture}, + {"toScreen", sdl_texture_toscreen}, {NULL, NULL}, }; @@ -1022,6 +1151,7 @@ int luaopen_core(lua_State *L) auxiliar_newclass(L, "physfs{zip}", fszipfile_reg); auxiliar_newclass(L, "line{core}", line_reg); auxiliar_newclass(L, "fov{core}", fov_reg); + auxiliar_newclass(L, "gl{texture}", sdl_texture_reg); auxiliar_newclass(L, "sdl{surface}", sdl_surface_reg); auxiliar_newclass(L, "sdl{font}", sdl_font_reg); luaL_openlib(L, "core.fov", fovlib, 0); diff --git a/src/display_sdl.h b/src/display_sdl.h index 2a3583e39b..6a422e4089 100644 --- a/src/display_sdl.h +++ b/src/display_sdl.h @@ -36,6 +36,8 @@ #include <SDL.h> #include <SDL_framerate.h> +#include <GL/gl.h> +#include <GL/glu.h> #ifdef __cplusplus extern "C" { diff --git a/src/main.c b/src/main.c index 316f5522af..f112105a1e 100644 --- a/src/main.c +++ b/src/main.c @@ -13,6 +13,9 @@ #include "physfs.h" #include "core_lua.h" +#define WIDTH 800 +#define HEIGHT 600 + lua_State *L = NULL; int current_mousehandler = LUA_NOREF; int current_keyhandler = LUA_NOREF; @@ -196,7 +199,7 @@ void on_tick() Frames++; { int t = SDL_GetTicks(); - if (t - T0 >= 5000) { + if (t - T0 >= 1000) { float seconds = (t - T0) / 1000.0; float fps = Frames / seconds; printf("%d ticks in %g seconds = %g TPS\n", Frames, seconds, fps); @@ -211,8 +214,8 @@ void on_redraw() static int Frames = 0; static int T0 = 0; - sdlLock(screen); - SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, 0x00, 0x00, 0x00)); + glClear( GL_COLOR_BUFFER_BIT); + glLoadIdentity(); if (current_game != LUA_NOREF) { @@ -224,16 +227,13 @@ void on_redraw() docall(L, 1, 0); } - sdlUnlock(screen); - - // finally display the screen - SDL_Flip(screen); + SDL_GL_SwapBuffers(); /* Gather our frames per second */ Frames++; { int t = SDL_GetTicks(); - if (t - T0 >= 5000) { + if (t - T0 >= 1000) { float seconds = (t - T0) / 1000.0; float fps = Frames / seconds; printf("%d frames in %g seconds = %g FPS\n", Frames, seconds, fps); @@ -287,6 +287,72 @@ Uint32 redraw_timer(Uint32 interval, void *param) return(interval); } +/* general OpenGL initialization function */ +int initGL() +{ + /* Enable smooth shading */ +// glShadeModel( GL_SMOOTH ); + + /* Set the background black */ + glClearColor( 0.0f, 0.0f, 0.0f, 1.0f ); + + /* Depth buffer setup */ +// glClearDepth( 1.0f ); + + /* Enables Depth Testing */ +// glEnable( GL_DEPTH_TEST ); + + /* The Type Of Depth Test To Do */ +// glDepthFunc( GL_LEQUAL ); + + /* Really Nice Perspective Calculations */ + // glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST ); + + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); +// glDisable(GL_DEPTH_TEST); + glColor4f(1.0f,1.0f,1.0f,1.0f); +// glAlphaFunc(GL_GREATER,0.1f); + + return( TRUE ); +} + +int resizeWindow(int width, int height) +{ + /* Height / width ration */ + GLfloat ratio; + + /* Protect against a divide by zero */ + if ( height == 0 ) + height = 1; + + ratio = ( GLfloat )width / ( GLfloat )height; + + glEnable( GL_TEXTURE_2D ); + + /* Setup our viewport. */ + glViewport( 0, 0, ( GLsizei )width, ( GLsizei )height ); + + /* change to the projection matrix and set our viewing volume. */ + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + + /* Set our perspective */ + //gluPerspective( 45.0f, ratio, 0.1f, 100.0f ); + glOrtho(0, width, height, 0, -100, 100); + + /* Make sure we're chaning the model view and not the projection */ + glMatrixMode( GL_MODELVIEW ); + + /* Reset The View */ + glLoadIdentity( ); + +// glEnable(GL_ALPHA_TEST); +// glColor4f(1.0f,1.0f,1.0f,1.0f); + + return( TRUE ); +} + /** * Program entry point. */ @@ -308,7 +374,7 @@ int main(int argc, char *argv[]) luaopen_mime_core(L); luaopen_struct(L); luaopen_profiler(L); -// luaopen_map(L); + luaopen_map(L); // Make the uids repository lua_newtable(L); @@ -320,7 +386,7 @@ int main(int argc, char *argv[]) printf("cannot initialize SDL: %s\n", SDL_GetError ()); return; } - screen = SDL_SetVideoMode(800, 600, 32, _DEFAULT_VIDEOMODE_FLAGS_); + screen = SDL_SetVideoMode(WIDTH, HEIGHT, 32, SDL_OPENGL | SDL_GL_DOUBLEBUFFER | SDL_HWPALETTE | SDL_HWSURFACE); if (screen==NULL) { printf("error opening screen: %s\n", SDL_GetError()); return; @@ -330,6 +396,11 @@ int main(int argc, char *argv[]) SDL_EnableKeyRepeat(300, 10); TTF_Init(); + /* Sets up OpenGL double buffering */ + SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 ); + initGL(); + resizeWindow(WIDTH, HEIGHT); + // And run the lua engine scripts luaL_loadfile(L, "/engine/init.lua"); docall(L, 0, 0); @@ -371,6 +442,8 @@ int main(int argc, char *argv[]) /* draw the scene */ on_tick(); +// on_redraw(); + } return 0; diff --git a/src/map.c b/src/map.c new file mode 100644 index 0000000000..93c2bb9871 --- /dev/null +++ b/src/map.c @@ -0,0 +1,137 @@ +#include "lua.h" +#include "lauxlib.h" +#include "lualib.h" +#include "auxiliar.h" +#include "types.h" +#include "map.h" +#include "script.h" +#include <SDL.h> +#include <SDL_ttf.h> + +static int map_new(lua_State *L) +{ + int w = luaL_checknumber(L, 1); + int h = luaL_checknumber(L, 2); + int mx = luaL_checknumber(L, 3); + int my = luaL_checknumber(L, 4); + int mwidth = luaL_checknumber(L, 5); + int mheight = luaL_checknumber(L, 6); + + map_type *map = (map_type*)lua_newuserdata(L, sizeof(map_type)); + auxiliar_setclass(L, "core{map}", -1); + + map->w = w; + map->h = h; + map->mx = mx; + map->my = my; + map->mwidth = mwidth; + map->mheight = mheight; + map->grids = calloc(w, sizeof(GLuint*)); + printf("size %d:%d :: %d\n", mwidth, mheight,mwidth * mheight); + + int i; + for (i = 0; i < w; i++) + { + map->grids[i] = calloc(h, sizeof(GLuint)); + } + + map->dlist = glGenLists(1); + + /* New compiled box display list */ + glNewList(map->dlist, GL_COMPILE); + glBegin(GL_QUADS); + glTexCoord2f(0,0); glVertex2f(0 , 0 ); + glTexCoord2f(0,1); glVertex2f(0 , 16 ); + glTexCoord2f(1,1); glVertex2f(16 , 16 ); + glTexCoord2f(1,0); glVertex2f(16 , 0 ); + glEnd(); + glEndList( ); + + return 1; +} + +static int map_free(lua_State *L) +{ + map_type *map = (map_type*)auxiliar_checkclass(L, "core{map}", 1); + int i; + + for (i = 0; i < map->w; i++) + { + free(map->grids[i]); + } + free(map->grids); + + lua_pushnumber(L, 1); + return 1; +} + +static int map_set_grid(lua_State *L) +{ + map_type *map = (map_type*)auxiliar_checkclass(L, "core{map}", 1); + int x = luaL_checknumber(L, 2); + int y = luaL_checknumber(L, 3); + GLuint *t = (GLuint*)auxiliar_checkclass(L, "gl{texture}", 4); + + map->grids[x][y] = *t; +} + +static int map_set_scroll(lua_State *L) +{ + map_type *map = (map_type*)auxiliar_checkclass(L, "core{map}", 1); + int x = luaL_checknumber(L, 2); + int y = luaL_checknumber(L, 3); + + map->mx = x; + map->my = y; +} + +static int map_to_screen(lua_State *L) +{ + map_type *map = (map_type*)auxiliar_checkclass(L, "core{map}", 1); + int x = luaL_checknumber(L, 2); + int y = luaL_checknumber(L, 3); + int i = 0, j = 0; + + for (i = map->mx; i < map->mx + map->mwidth; i++) + { + for (j = map->my; j < map->my + map->mheight; j++) + { + if ((i >= map->w) || (j >= map->h) || (!map->grids[i][j])) continue; + + int dx = x + (i - map->mx) * 16; + int dy = y + (j - map->my) * 16; + + glBindTexture(GL_TEXTURE_2D, map->grids[i][j]); + glBegin(GL_QUADS); + glTexCoord2f(0,0); glVertex3f(0 +dx, 0 +dy,-99); + glTexCoord2f(1,0); glVertex3f(16 +dx, 0 +dy,-99); + glTexCoord2f(1,1); glVertex3f(16 +dx, 16 +dy,-99); + glTexCoord2f(0,1); glVertex3f(0 +dx, 16 +dy,-99); + glEnd(); + } + } +} + +static const struct luaL_reg maplib[] = +{ + {"newMap", map_new}, + {NULL, NULL}, +}; + +static const struct luaL_reg map_reg[] = +{ + {"__gc", map_free}, + {"close", map_free}, + {"setGrid", map_set_grid}, + {"setScroll", map_set_scroll}, + {"toScreen", map_to_screen}, + {NULL, NULL}, +}; + +int luaopen_map(lua_State *L) +{ + auxiliar_newclass(L, "core{map}", map_reg); +// auxiliar_newclass(L, "core{level}", level_reg); + luaL_openlib(L, "core.map", maplib, 0); + return 1; +} diff --git a/src/map.h b/src/map.h new file mode 100644 index 0000000000..6f319d08f9 --- /dev/null +++ b/src/map.h @@ -0,0 +1,19 @@ +#ifndef _MAP_H_ +#define _MAP_H_ + +#include <GL/gl.h> + +typedef struct { + GLuint **grids; + + GLuint dlist; + + // Map size + int w; + int h; + + // Scrolling + int mx, my, mwidth, mheight; +} map_type; + +#endif -- GitLab