I've seen tutorials on line of sight vision using ray tracing. I forget where (RogueBasin?) but I'm sure Google has you covered.
I'd use a recursive flood fill. Maybe something like:
void lightCell( cell, lightValue )
{
if( lightValue <= 0 ) return;
if( !isCellLightable(cell) ) return;
if( cell.lightValue >= lightValue ) return;
cell.lightValue = lightValue;
lightCell( cellAbove(cell), lightValue - 10 );
lightCell( cellToRightOf(cell), lightValue - 10 );
lightCell( cellBelow(cell), lightValue - 10 );
lightCell( cellToLeftOf(cell), lightValue - 10 );
}
Each frame, you can add a decay value to the light in each cell, causing the light to naturally diminish.
Using a recursive flood fill over a large area will absolutely overflow your stack, but if you use it for relatively small areas, it should be okay.
Also, this approach is more for ambient light, as it absolutely will spill around corners and get into cracks and crevices. However, (I haven't tried this) you can manipulate the order and light value of how you visit each cell to emulate directional light. For instance, if you are projecting light to the right, don't add light to the left of the cell and can have a higher drop off (lightValue-20) for cells above and below it. You can also do diagonals. Then just do a recursive, directional light fill N+S+E+W.