On Wed, Oct 10, 2012 at 12:46 PM, Carsten Haitzler <[email protected]> wrote:
> On Mon, 1 Oct 2012 13:33:35 +0200 Vincent Torri <[email protected]> 
> said:
>
>> hey
>>
>> i'm using some evas object green lines, and there are some black
>> pixels that are also drawn. See attached file. Does someone see why ?
>
> wtf? that's odd. the software engine should all render the same regardless of
> where it is...do u have the src so i can test? i've never seen this and it
> shouldn't happen - the line code literally is ancient and hasnt been touched 
> for
> years. i am pretty sure it worked when i wrote it and has worked since... but
> maybe some minor bug crept in...

here it is

Vincent
/* gcc -g -Wall -o wolf2 wolf2.c `pkg-config --cflags --libs ecore-evas ecore evas eina evil` */

#include <stdio.h>
#include <math.h>

#include <Evas.h>
#include <Ecore.h>
#include <Ecore_Evas.h>

#define round(x) ((x)>=0?(long)((x)+0.5):(long)((x)-0.5))

typedef struct _W_Player W_Player;
typedef struct _W_World W_World;

struct _W_Player
{
  double x;
  double y;
  int dir; /* -1, 1 ou 0 */
  double rot; /* angle courant */
  int speed; /* -1, 1 ou 0 */
  double speed_move;
  double speed_rot;

  Evas_Object *o; /* player */
  Evas_Object *o_line; /* direction */

  int rays_num;
  Evas_Object **o_rays;
};

struct _W_World
{
  int map[24][32];
  int map_width;
  int map_height;
  int map_scale;
  int screen_width;
  int strip_width;
  double fov;
  double view_dist;
  Evas_Object *o_map;
  W_Player player;
};

static int map_def[24][32] = {
  {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
  {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
  {1,0,0,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
  {1,0,0,2,0,2,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1},
  {1,0,0,2,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
  {1,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
  {1,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,2,2,1},
  {1,0,0,2,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
  {1,0,0,2,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
  {1,0,0,2,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
  {1,0,0,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,2,2,1},
  {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
  {1,0,0,0,0,0,0,0,0,2,2,2,0,0,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
  {1,0,0,0,0,0,0,0,0,2,2,2,0,0,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
  {1,0,0,0,0,0,0,0,0,2,2,2,0,0,2,2,2,0,0,0,0,0,0,0,0,0,2,2,2,2,2,1},
  {1,0,0,0,0,0,0,0,0,2,2,2,0,0,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
  {1,0,0,2,0,0,2,2,0,2,2,2,2,2,2,2,2,0,2,2,2,0,0,2,0,0,0,0,0,0,0,1},
  {1,0,0,2,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,2,0,0,0,0,0,0,0,1},
  {1,0,0,2,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,2,0,0,0,0,0,0,0,1},
  {1,0,0,2,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,2,0,0,0,0,0,0,0,1},
  {1,0,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,0,0,0,1},
  {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
  {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
  {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
};

static W_World world;

static void w_player_rays_cast();

static void
w_world_init(Evas *evas)
{
  memcpy(world.map, map_def, sizeof(map_def));
  world.map_width = 32;
  world.map_height = 24;
  world.map_scale = 8;
  world.screen_width = 320;
  world.strip_width = 4;
  world.fov = 60 * M_PI / 180;
  world.view_dist = (world.screen_width / 2.0) / tan(world.fov / 2.0);

  world.player.x = 16 * world.map_scale;
  world.player.y = 10 * world.map_scale;
  world.player.dir = 0;
  world.player.rot = 0;
  world.player.speed = 0;
  world.player.speed_move = 1.44;
  world.player.speed_rot = 5 * M_PI / 180;
  world.player.rays_num = world.screen_width / world.strip_width;
}

static void
w_world_draw(Evas *evas)
{
  Evas_Object *o;
  int i;
  int j;
  int ii;
  int jj;
  int w;
  int h;
  unsigned int *m;
  unsigned int *iter;

  w = world.map_width * world.map_scale;
  h = world.map_height * world.map_scale;

  o = evas_object_image_add(evas);
  evas_object_move(o, 0, 0);
  evas_object_resize(o, w, h);
  evas_object_color_set(o, 255, 255, 255, 255);

  evas_object_image_size_set(o, w, h);
  evas_object_image_fill_set(o, 0, 0, w, h);
  m = (unsigned int *)evas_object_image_data_get(o, 1);
  if (!m)
    return;

  iter = m;
  for (j = 0; j < world.map_height; j++)
    for (jj = 0; jj < world.map_scale; jj++)
      for (i = 0; i < world.map_width; i++)
	for (ii = 0; ii < world.map_scale; ii++, iter++)
	  {
	    if (world.map[j][i] > 0)
	      *iter = 200 << 24 | 200 << 16 | 200 << 8 | 200;
	    else
	      *iter = 255 << 24 | 255 << 16 | 255 << 8 | 255;
	  }

  evas_object_image_data_set(o, m);
  evas_object_image_data_update_add(o, 0, 0, w, h);
  evas_object_show(o);
  world.o_map = o;

  o = evas_object_rectangle_add(evas);
  evas_object_move(o,
		   world.player.x - 1,
		   world.player.y - 1);
  evas_object_resize(o, 4, 4);
  evas_object_color_set(o, 255, 0, 0, 255);
  evas_object_show(o);
  world.player.o = o;

  o = evas_object_line_add(evas);
  evas_object_line_xy_set(o,
			  world.player.x,
			  world.player.y,
			  world.player.x + 1 + 32 * cos(world.player.rot),
			  world.player.y + 1 + 32 * sin(world.player.rot));
  evas_object_color_set(o, 255, 0, 0, 255);
  evas_object_show(o);
  world.player.o_line = o;

  world.player.o_rays = (Evas_Object **)malloc(world.player.rays_num * sizeof(Evas_Object *));
  for (i = 0; i < world.player.rays_num; i++)
    {
      Evas_Object *o;

      o = evas_object_line_add(evas);
      evas_object_color_set(o, 0, 30, 0, 75);
      world.player.o_rays[i] = o;
    }

  w_player_rays_cast();
}

static double
modulo(double v, double per)
{
  if (v >= 0)
    {
      while (v >= per) v -= per;
    }
  else
    {
      while (v < 0) v += per;
    }

  return v;
}

static void
w_player_move()
{
  double step;
  double x;
  double y;

  step = world.player.speed * world.player.speed_move;
  world.player.rot += world.player.dir * world.player.speed_rot;
  world.player.rot = modulo(world.player.rot, 2.0 * M_PI);
  x = world.player.x + cos(world.player.rot) * step;
  y = world.player.y + sin(world.player.rot) * step;

  if ((x < 0) ||
      (y < 0) ||
      (x >= world.map_width * world.map_scale) ||
      (y >= world.map_height * world.map_scale))
    return;

  if (world.map[(int)floor(y / world.map_scale)][(int)floor(x / world.map_scale)] != 0)
    return;

  world.player.x = x;
  world.player.y = y;

  evas_object_move(world.player.o,
		   world.player.x - 1,
		   world.player.y - 1);
  evas_object_line_xy_set(world.player.o_line,
			  world.player.x,
			  world.player.y,
			  world.player.x + 1 + 32 * cos(world.player.rot),
			  world.player.y + 1 + 32 * sin(world.player.rot));
}

static void
w_player_ray_cast(double ray_angle, int strip_idx)
{
  int right, up;
  double angle_sin, angle_cos;
  double dist = 0;
  double hit_x = 0, hit_y = 0;
  double texture_x;
  double slope;
  double dx, dy;
  double x, y;

  ray_angle = modulo(ray_angle, 2.0 * M_PI);

  right = (ray_angle > 2.0 * M_PI * 0.75) || (ray_angle < 2.0 * M_PI * 0.25);
  up = (ray_angle < 0) || (ray_angle > M_PI);

  angle_sin = sin(ray_angle);
  angle_cos = cos(ray_angle);

  slope = angle_sin / angle_cos;
  dx = right ? 1.0 / world.map_scale : -1.0 / world.map_scale;
  dy = dx * slope;

  x = world.player.x;
  y = world.player.y + (x - world.player.x) * slope;

  while ((x >= 0) && (x < world.map_width * world.map_scale) &&
	 (y >= 0) && (y < world.map_height * world.map_scale))
    {
      double wall_x, wall_y;

      wall_x = floor(x / world.map_scale);
      wall_y = floor(y / world.map_scale);
      if (world.map[(int)wall_y][(int)wall_x] > 0)
	{
	  double dist_x, dist_y;

	  dist_x = x - world.player.x;
	  dist_y = y - world.player.y;
	  dist = dist_x * dist_x + dist_y * dist_y;
	  texture_x = modulo(y, world.map_scale);
	  if (!right) texture_x = world.map_scale - texture_x;

	  hit_x = x;
	  hit_y = y;
	  break;
	}
      x += dx;
      y += dy;
    }

  slope = angle_cos / angle_sin;
  dy = up ? -1.0 / world.map_scale : 1.0 / world.map_scale;
  dx = dy * slope;

  y = world.player.y;
  x = world.player.x + (y - world.player.y) * slope;

  while ((x >= 0) && (x < world.map_width * world.map_scale) &&
	 (y >= 0) && (y < world.map_height * world.map_scale))
    {
      double wall_x, wall_y;

      wall_y = floor(y / world.map_scale);
      wall_x = floor(x / world.map_scale);
      if (world.map[(int)wall_y][(int)wall_x] > 0)
	{
	  double dist_x, dist_y;
	  double block_dist;

	  dist_x = x - world.player.x;
	  dist_y = y - world.player.y;
	  block_dist = dist_x * dist_x + dist_y * dist_y;
	  if ((dist == 0) || (block_dist < dist))
	    {
	      dist = block_dist;
	      hit_x = x;
	      hit_y = y;
	      texture_x = modulo(x, world.map_scale);
	      if (!up) texture_x = world.map_scale - texture_x;
	    }
	  break;
	}

      x += dx;
      y += dy;
    }

  if (dist != 0)
    {
      evas_object_line_xy_set(world.player.o_rays[strip_idx],
			      world.player.x,
			      world.player.y,
			      hit_x,
			      hit_y);
      evas_object_show(world.player.o_rays[strip_idx]);
    }
}

static void
w_player_rays_cast()
{
  int i;

  for (i = 0; i < world.player.rays_num; i++)
    {
      double ray_pos;
      double ray_dist;
      double ray_angle;

      ray_pos = (-world.player.rays_num / 2.0 + i) * world.strip_width;
      ray_dist = sqrt(ray_pos * ray_pos + world.view_dist * world.view_dist);
      ray_angle = asin(ray_pos / ray_dist);

      w_player_ray_cast(world.player.rot + ray_angle, i);
    }
}

static void
_key_down_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)
{
  Evas_Event_Key_Down *ev;

  ev = (Evas_Event_Key_Down *)event_info;

  if (strcmp(ev->keyname, "Up") == 0)
    world.player.speed = 1;

  if (strcmp(ev->keyname, "Down") == 0)
    world.player.speed = -1;

  if (strcmp(ev->keyname, "Left") == 0)
    world.player.dir = -1;

  if (strcmp(ev->keyname, "Right") == 0)
    world.player.dir = 1;

  w_player_move();
  w_player_rays_cast();
}

static void
_key_up_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)
{
  Evas_Event_Key_Up *ev;

  ev = (Evas_Event_Key_Up *)event_info;

  if ((strcmp(ev->keyname, "Up") == 0) ||
      (strcmp(ev->keyname, "Down") == 0))
    world.player.speed = 0;

  if ((strcmp(ev->keyname, "Left") == 0) ||
      (strcmp(ev->keyname, "Right") == 0))
    world.player.dir = 0;

  if (strcmp(ev->keyname, "q") == 0)
    ecore_main_loop_quit();
}

static void _quit_cb(Ecore_Evas *ee)
{
  ecore_main_loop_quit();
}

int main()
{
  Ecore_Evas *ee;
  Evas *evas;
  int w;
  int h;

  if (!ecore_evas_init())
    return -1;

  ee = ecore_evas_new(NULL, 10, 10, 0, 0, NULL);
  if (!ee)
    goto shutdown_ecore_evas;

  ecore_evas_title_set(ee, "Wolfenstein");
  ecore_evas_callback_delete_request_set(ee, _quit_cb);

  evas = ecore_evas_get(ee);

  w_world_init(evas);
  w = world.map_width * world.map_scale;
  h = world.map_height * world.map_scale;

  w_world_draw(evas);

  evas_object_focus_set(world.o_map, EINA_TRUE);
  evas_object_event_callback_add(world.o_map, EVAS_CALLBACK_KEY_DOWN, _key_down_cb, NULL);
  evas_object_event_callback_add(world.o_map, EVAS_CALLBACK_KEY_UP, _key_up_cb, NULL);

  ecore_evas_resize(ee, w, h);
  ecore_evas_show(ee);

  ecore_main_loop_begin();

  ecore_evas_shutdown();

  return 0;

 shutdown_ecore_evas:
  ecore_evas_shutdown();

  return -1;
}
------------------------------------------------------------------------------
Don't let slow site performance ruin your business. Deploy New Relic APM
Deploy New Relic app performance management and know exactly
what is happening inside your Ruby, Python, PHP, Java, and .NET app
Try New Relic at no cost today and get our sweet Data Nerd shirt too!
http://p.sf.net/sfu/newrelic-dev2dev
_______________________________________________
enlightenment-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/enlightenment-devel

Reply via email to